diff options
144 files changed, 1754 insertions, 4266 deletions
diff --git a/Documentation/ABI/testing/sysfs-driver-qat_kpt b/Documentation/ABI/testing/sysfs-driver-qat_kpt index c6480ea1fa4f..80831ce3d2ca 100644 --- a/Documentation/ABI/testing/sysfs-driver-qat_kpt +++ b/Documentation/ABI/testing/sysfs-driver-qat_kpt @@ -14,7 +14,8 @@ Contact: qat-linux@intel.com Description: (RW) Enables or disables Key Protection Technology (KPT). - Write 1 to enable KPT, or 0 to disable it. + Write 1 to enable KPT, or 0 to disable it. The device must be + in the down state before changing the KPT state. Example usage:: diff --git a/Documentation/devicetree/bindings/crypto/hisilicon,hip06-sec.yaml b/Documentation/devicetree/bindings/crypto/hisilicon,hip06-sec.yaml deleted file mode 100644 index 2bfac9d1c020..000000000000 --- a/Documentation/devicetree/bindings/crypto/hisilicon,hip06-sec.yaml +++ /dev/null @@ -1,134 +0,0 @@ -# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) -%YAML 1.2 ---- -$id: http://devicetree.org/schemas/crypto/hisilicon,hip06-sec.yaml# -$schema: http://devicetree.org/meta-schemas/core.yaml# - -title: Hisilicon hip06/hip07 Security Accelerator - -maintainers: - - Jonathan Cameron <Jonathan.Cameron@huawei.com> - -properties: - compatible: - enum: - - hisilicon,hip06-sec - - hisilicon,hip07-sec - - reg: - items: - - description: Registers for backend processing engines - - description: Registers for common functionality - - description: Registers for queue 0 - - description: Registers for queue 1 - - description: Registers for queue 2 - - description: Registers for queue 3 - - description: Registers for queue 4 - - description: Registers for queue 5 - - description: Registers for queue 6 - - description: Registers for queue 7 - - description: Registers for queue 8 - - description: Registers for queue 9 - - description: Registers for queue 10 - - description: Registers for queue 11 - - description: Registers for queue 12 - - description: Registers for queue 13 - - description: Registers for queue 14 - - description: Registers for queue 15 - - interrupts: - items: - - description: SEC unit error queue interrupt - - description: Completion interrupt for queue 0 - - description: Error interrupt for queue 0 - - description: Completion interrupt for queue 1 - - description: Error interrupt for queue 1 - - description: Completion interrupt for queue 2 - - description: Error interrupt for queue 2 - - description: Completion interrupt for queue 3 - - description: Error interrupt for queue 3 - - description: Completion interrupt for queue 4 - - description: Error interrupt for queue 4 - - description: Completion interrupt for queue 5 - - description: Error interrupt for queue 5 - - description: Completion interrupt for queue 6 - - description: Error interrupt for queue 6 - - description: Completion interrupt for queue 7 - - description: Error interrupt for queue 7 - - description: Completion interrupt for queue 8 - - description: Error interrupt for queue 8 - - description: Completion interrupt for queue 9 - - description: Error interrupt for queue 9 - - description: Completion interrupt for queue 10 - - description: Error interrupt for queue 10 - - description: Completion interrupt for queue 11 - - description: Error interrupt for queue 11 - - description: Completion interrupt for queue 12 - - description: Error interrupt for queue 12 - - description: Completion interrupt for queue 13 - - description: Error interrupt for queue 13 - - description: Completion interrupt for queue 14 - - description: Error interrupt for queue 14 - - description: Completion interrupt for queue 15 - - description: Error interrupt for queue 15 - - dma-coherent: true - - iommus: - maxItems: 1 - -required: - - compatible - - reg - - interrupts - - dma-coherent - -additionalProperties: false - -examples: - - | - bus { - #address-cells = <2>; - #size-cells = <2>; - - crypto@400d2000000 { - compatible = "hisilicon,hip07-sec"; - reg = <0x400 0xd0000000 0x0 0x10000 - 0x400 0xd2000000 0x0 0x10000 - 0x400 0xd2010000 0x0 0x10000 - 0x400 0xd2020000 0x0 0x10000 - 0x400 0xd2030000 0x0 0x10000 - 0x400 0xd2040000 0x0 0x10000 - 0x400 0xd2050000 0x0 0x10000 - 0x400 0xd2060000 0x0 0x10000 - 0x400 0xd2070000 0x0 0x10000 - 0x400 0xd2080000 0x0 0x10000 - 0x400 0xd2090000 0x0 0x10000 - 0x400 0xd20a0000 0x0 0x10000 - 0x400 0xd20b0000 0x0 0x10000 - 0x400 0xd20c0000 0x0 0x10000 - 0x400 0xd20d0000 0x0 0x10000 - 0x400 0xd20e0000 0x0 0x10000 - 0x400 0xd20f0000 0x0 0x10000 - 0x400 0xd2100000 0x0 0x10000>; - interrupts = <576 4>, - <577 1>, <578 4>, - <579 1>, <580 4>, - <581 1>, <582 4>, - <583 1>, <584 4>, - <585 1>, <586 4>, - <587 1>, <588 4>, - <589 1>, <590 4>, - <591 1>, <592 4>, - <593 1>, <594 4>, - <595 1>, <596 4>, - <597 1>, <598 4>, - <599 1>, <600 4>, - <601 1>, <602 4>, - <603 1>, <604 4>, - <605 1>, <606 4>, - <607 1>, <608 4>; - dma-coherent; - iommus = <&p1_smmu_alg_a 0x600>; - }; - }; diff --git a/Documentation/devicetree/bindings/trivial-devices.yaml b/Documentation/devicetree/bindings/trivial-devices.yaml index 2de8eb09cb7d..3b7876c5a45d 100644 --- a/Documentation/devicetree/bindings/trivial-devices.yaml +++ b/Documentation/devicetree/bindings/trivial-devices.yaml @@ -69,6 +69,8 @@ properties: - asteralabs,pt5161l # ATECC508A - i2c h/w elliptic curve crypto module - atmel,atecc508a + # ATECC608A - i2c h/w elliptic curve crypto module + - atmel,atecc608a # ATECC608B - i2c h/w elliptic curve crypto module - atmel,atecc608b # ATSHA204 - i2c h/w symmetric crypto module diff --git a/MAINTAINERS b/MAINTAINERS index b4c1b751698d..8adbcdf780f0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1088,7 +1088,6 @@ F: include/linux/cdx/* AMD CRYPTOGRAPHIC COPROCESSOR (CCP) DRIVER M: Tom Lendacky <thomas.lendacky@amd.com> -M: John Allen <john.allen@amd.com> L: linux-crypto@vger.kernel.org S: Supported F: drivers/crypto/ccp/ @@ -10420,7 +10419,7 @@ F: include/video/ FREESCALE CAAM (Cryptographic Acceleration and Assurance Module) DRIVER M: Horia Geantă <horia.geanta@nxp.com> M: Pankaj Gupta <pankaj.gupta@nxp.com> -M: Gaurav Jain <gaurav.jain@nxp.com> +M: Sahil Malhotra <sahil.malhotra@nxp.com> L: linux-crypto@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/crypto/fsl,sec-v4.0* @@ -12523,6 +12522,7 @@ F: drivers/crypto/nx/Makefile F: drivers/crypto/nx/nx-842* F: include/linux/sw842.h F: lib/842/ +F: lib/tests/842_decompress_kunit.c IBM Power in-Nest Crypto Acceleration M: Breno Leitão <leitao@debian.org> @@ -22582,6 +22582,15 @@ S: Maintained F: Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml F: drivers/i2c/busses/i2c-qcom-cci.c +QUALCOMM INLINE CRYPTO ENGINE DRIVER +M: Abel Vesa <abelvesa@kernel.org> +L: linux-arm-msm@vger.kernel.org +L: linux-crypto@vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/crypto/qcom,inline-crypto-engine.yaml +F: drivers/soc/qcom/ice.c +F: include/soc/qcom/ice.h + QUALCOMM INTERCONNECT BWMON DRIVER M: Krzysztof Kozlowski <krzk@kernel.org> L: linux-arm-msm@vger.kernel.org diff --git a/arch/arm/crypto/aes-neonbs-glue.c b/arch/arm/crypto/aes-neonbs-glue.c index c49ddafc54f3..f0c8bfd2ac8f 100644 --- a/arch/arm/crypto/aes-neonbs-glue.c +++ b/arch/arm/crypto/aes-neonbs-glue.c @@ -60,7 +60,7 @@ static int aesbs_setkey(struct crypto_skcipher *tfm, const u8 *in_key, unsigned int key_len) { struct aesbs_ctx *ctx = crypto_skcipher_ctx(tfm); - struct crypto_aes_ctx rk; + struct crypto_aes_ctx rk __cleanup(aes_zeroize_ctx); int err; err = aes_expandkey(&rk, in_key, key_len); diff --git a/arch/arm64/boot/dts/hisilicon/hip07.dtsi b/arch/arm64/boot/dts/hisilicon/hip07.dtsi index 00a6bfa7478c..d175e242ee96 100644 --- a/arch/arm64/boot/dts/hisilicon/hip07.dtsi +++ b/arch/arm64/boot/dts/hisilicon/hip07.dtsi @@ -1113,74 +1113,6 @@ num-pins = <2>; }; }; - p0_mbigen_alg_a:interrupt-controller@d0080000 { - compatible = "hisilicon,mbigen-v2"; - reg = <0x0 0xd0080000 0x0 0x10000>; - - p0_mbigen_sec_a: intc_sec { - msi-parent = <&p0_its_dsa_a 0x40400>; - interrupt-controller; - #interrupt-cells = <2>; - num-pins = <33>; - }; - p0_mbigen_smmu_alg_a: intc_smmu_alg { - msi-parent = <&p0_its_dsa_a 0x40b1b>; - interrupt-controller; - #interrupt-cells = <2>; - num-pins = <3>; - }; - }; - p0_mbigen_alg_b:interrupt-controller@8,d0080000 { - compatible = "hisilicon,mbigen-v2"; - reg = <0x8 0xd0080000 0x0 0x10000>; - - p0_mbigen_sec_b: intc_sec { - msi-parent = <&p0_its_dsa_b 0x42400>; - interrupt-controller; - #interrupt-cells = <2>; - num-pins = <33>; - }; - p0_mbigen_smmu_alg_b: intc_smmu_alg { - msi-parent = <&p0_its_dsa_b 0x42b1b>; - interrupt-controller; - #interrupt-cells = <2>; - num-pins = <3>; - }; - }; - p1_mbigen_alg_a:interrupt-controller@400,d0080000 { - compatible = "hisilicon,mbigen-v2"; - reg = <0x400 0xd0080000 0x0 0x10000>; - - p1_mbigen_sec_a: intc_sec { - msi-parent = <&p1_its_dsa_a 0x44400>; - interrupt-controller; - #interrupt-cells = <2>; - num-pins = <33>; - }; - p1_mbigen_smmu_alg_a: intc_smmu_alg { - msi-parent = <&p1_its_dsa_a 0x44b1b>; - interrupt-controller; - #interrupt-cells = <2>; - num-pins = <3>; - }; - }; - p1_mbigen_alg_b:interrupt-controller@408,d0080000 { - compatible = "hisilicon,mbigen-v2"; - reg = <0x408 0xd0080000 0x0 0x10000>; - - p1_mbigen_sec_b: intc_sec { - msi-parent = <&p1_its_dsa_b 0x46400>; - interrupt-controller; - #interrupt-cells = <2>; - num-pins = <33>; - }; - p1_mbigen_smmu_alg_b: intc_smmu_alg { - msi-parent = <&p1_its_dsa_b 0x46b1b>; - interrupt-controller; - #interrupt-cells = <2>; - num-pins = <3>; - }; - }; p0_mbigen_dsa_a: interrupt-controller@c0080000 { compatible = "hisilicon,mbigen-v2"; reg = <0x0 0xc0080000 0x0 0x10000>; @@ -1237,54 +1169,6 @@ hisilicon,broken-prefetch-cmd; status = "disabled"; }; - p0_smmu_alg_a: iommu@d0040000 { - compatible = "arm,smmu-v3"; - reg = <0x0 0xd0040000 0x0 0x20000>; - interrupt-parent = <&p0_mbigen_smmu_alg_a>; - interrupts = <733 1>, - <734 1>, - <735 1>; - interrupt-names = "eventq", "gerror", "priq"; - #iommu-cells = <1>; - dma-coherent; - hisilicon,broken-prefetch-cmd; - }; - p0_smmu_alg_b: iommu@8d0040000 { - compatible = "arm,smmu-v3"; - reg = <0x8 0xd0040000 0x0 0x20000>; - interrupt-parent = <&p0_mbigen_smmu_alg_b>; - interrupts = <733 1>, - <734 1>, - <735 1>; - interrupt-names = "eventq", "gerror", "priq"; - #iommu-cells = <1>; - dma-coherent; - hisilicon,broken-prefetch-cmd; - }; - p1_smmu_alg_a: iommu@400d0040000 { - compatible = "arm,smmu-v3"; - reg = <0x400 0xd0040000 0x0 0x20000>; - interrupt-parent = <&p1_mbigen_smmu_alg_a>; - interrupts = <733 1>, - <734 1>, - <735 1>; - interrupt-names = "eventq", "gerror", "priq"; - #iommu-cells = <1>; - dma-coherent; - hisilicon,broken-prefetch-cmd; - }; - p1_smmu_alg_b: iommu@408d0040000 { - compatible = "arm,smmu-v3"; - reg = <0x408 0xd0040000 0x0 0x20000>; - interrupt-parent = <&p1_mbigen_smmu_alg_b>; - interrupts = <733 1>, - <734 1>, - <735 1>; - interrupt-names = "eventq", "gerror", "priq"; - #iommu-cells = <1>; - dma-coherent; - hisilicon,broken-prefetch-cmd; - }; soc { compatible = "simple-bus"; @@ -1745,170 +1629,6 @@ 0x0 0 0 4 &mbigen_pcie2_a 671 4>; status = "disabled"; }; - p0_sec_a: crypto@d0000000 { - compatible = "hisilicon,hip07-sec"; - reg = <0x0 0xd0000000 0x0 0x10000>, - <0x0 0xd2000000 0x0 0x10000>, - <0x0 0xd2010000 0x0 0x10000>, - <0x0 0xd2020000 0x0 0x10000>, - <0x0 0xd2030000 0x0 0x10000>, - <0x0 0xd2040000 0x0 0x10000>, - <0x0 0xd2050000 0x0 0x10000>, - <0x0 0xd2060000 0x0 0x10000>, - <0x0 0xd2070000 0x0 0x10000>, - <0x0 0xd2080000 0x0 0x10000>, - <0x0 0xd2090000 0x0 0x10000>, - <0x0 0xd20a0000 0x0 0x10000>, - <0x0 0xd20b0000 0x0 0x10000>, - <0x0 0xd20c0000 0x0 0x10000>, - <0x0 0xd20d0000 0x0 0x10000>, - <0x0 0xd20e0000 0x0 0x10000>, - <0x0 0xd20f0000 0x0 0x10000>, - <0x0 0xd2100000 0x0 0x10000>; - interrupt-parent = <&p0_mbigen_sec_a>; - iommus = <&p0_smmu_alg_a 0x600>; - dma-coherent; - interrupts = <576 4>, - <577 1>, <578 4>, - <579 1>, <580 4>, - <581 1>, <582 4>, - <583 1>, <584 4>, - <585 1>, <586 4>, - <587 1>, <588 4>, - <589 1>, <590 4>, - <591 1>, <592 4>, - <593 1>, <594 4>, - <595 1>, <596 4>, - <597 1>, <598 4>, - <599 1>, <600 4>, - <601 1>, <602 4>, - <603 1>, <604 4>, - <605 1>, <606 4>, - <607 1>, <608 4>; - }; - p0_sec_b: crypto@8d0000000 { - compatible = "hisilicon,hip07-sec"; - reg = <0x8 0xd0000000 0x0 0x10000>, - <0x8 0xd2000000 0x0 0x10000>, - <0x8 0xd2010000 0x0 0x10000>, - <0x8 0xd2020000 0x0 0x10000>, - <0x8 0xd2030000 0x0 0x10000>, - <0x8 0xd2040000 0x0 0x10000>, - <0x8 0xd2050000 0x0 0x10000>, - <0x8 0xd2060000 0x0 0x10000>, - <0x8 0xd2070000 0x0 0x10000>, - <0x8 0xd2080000 0x0 0x10000>, - <0x8 0xd2090000 0x0 0x10000>, - <0x8 0xd20a0000 0x0 0x10000>, - <0x8 0xd20b0000 0x0 0x10000>, - <0x8 0xd20c0000 0x0 0x10000>, - <0x8 0xd20d0000 0x0 0x10000>, - <0x8 0xd20e0000 0x0 0x10000>, - <0x8 0xd20f0000 0x0 0x10000>, - <0x8 0xd2100000 0x0 0x10000>; - interrupt-parent = <&p0_mbigen_sec_b>; - iommus = <&p0_smmu_alg_b 0x600>; - dma-coherent; - interrupts = <576 4>, - <577 1>, <578 4>, - <579 1>, <580 4>, - <581 1>, <582 4>, - <583 1>, <584 4>, - <585 1>, <586 4>, - <587 1>, <588 4>, - <589 1>, <590 4>, - <591 1>, <592 4>, - <593 1>, <594 4>, - <595 1>, <596 4>, - <597 1>, <598 4>, - <599 1>, <600 4>, - <601 1>, <602 4>, - <603 1>, <604 4>, - <605 1>, <606 4>, - <607 1>, <608 4>; - }; - p1_sec_a: crypto@400d0000000 { - compatible = "hisilicon,hip07-sec"; - reg = <0x400 0xd0000000 0x0 0x10000>, - <0x400 0xd2000000 0x0 0x10000>, - <0x400 0xd2010000 0x0 0x10000>, - <0x400 0xd2020000 0x0 0x10000>, - <0x400 0xd2030000 0x0 0x10000>, - <0x400 0xd2040000 0x0 0x10000>, - <0x400 0xd2050000 0x0 0x10000>, - <0x400 0xd2060000 0x0 0x10000>, - <0x400 0xd2070000 0x0 0x10000>, - <0x400 0xd2080000 0x0 0x10000>, - <0x400 0xd2090000 0x0 0x10000>, - <0x400 0xd20a0000 0x0 0x10000>, - <0x400 0xd20b0000 0x0 0x10000>, - <0x400 0xd20c0000 0x0 0x10000>, - <0x400 0xd20d0000 0x0 0x10000>, - <0x400 0xd20e0000 0x0 0x10000>, - <0x400 0xd20f0000 0x0 0x10000>, - <0x400 0xd2100000 0x0 0x10000>; - interrupt-parent = <&p1_mbigen_sec_a>; - iommus = <&p1_smmu_alg_a 0x600>; - dma-coherent; - interrupts = <576 4>, - <577 1>, <578 4>, - <579 1>, <580 4>, - <581 1>, <582 4>, - <583 1>, <584 4>, - <585 1>, <586 4>, - <587 1>, <588 4>, - <589 1>, <590 4>, - <591 1>, <592 4>, - <593 1>, <594 4>, - <595 1>, <596 4>, - <597 1>, <598 4>, - <599 1>, <600 4>, - <601 1>, <602 4>, - <603 1>, <604 4>, - <605 1>, <606 4>, - <607 1>, <608 4>; - }; - p1_sec_b: crypto@408d0000000 { - compatible = "hisilicon,hip07-sec"; - reg = <0x408 0xd0000000 0x0 0x10000>, - <0x408 0xd2000000 0x0 0x10000>, - <0x408 0xd2010000 0x0 0x10000>, - <0x408 0xd2020000 0x0 0x10000>, - <0x408 0xd2030000 0x0 0x10000>, - <0x408 0xd2040000 0x0 0x10000>, - <0x408 0xd2050000 0x0 0x10000>, - <0x408 0xd2060000 0x0 0x10000>, - <0x408 0xd2070000 0x0 0x10000>, - <0x408 0xd2080000 0x0 0x10000>, - <0x408 0xd2090000 0x0 0x10000>, - <0x408 0xd20a0000 0x0 0x10000>, - <0x408 0xd20b0000 0x0 0x10000>, - <0x408 0xd20c0000 0x0 0x10000>, - <0x408 0xd20d0000 0x0 0x10000>, - <0x408 0xd20e0000 0x0 0x10000>, - <0x408 0xd20f0000 0x0 0x10000>, - <0x408 0xd2100000 0x0 0x10000>; - interrupt-parent = <&p1_mbigen_sec_b>; - iommus = <&p1_smmu_alg_b 0x600>; - dma-coherent; - interrupts = <576 4>, - <577 1>, <578 4>, - <579 1>, <580 4>, - <581 1>, <582 4>, - <583 1>, <584 4>, - <585 1>, <586 4>, - <587 1>, <588 4>, - <589 1>, <590 4>, - <591 1>, <592 4>, - <593 1>, <594 4>, - <595 1>, <596 4>, - <597 1>, <598 4>, - <599 1>, <600 4>, - <601 1>, <602 4>, - <603 1>, <604 4>, - <605 1>, <606 4>, - <607 1>, <608 4>; - }; }; }; diff --git a/arch/arm64/crypto/aes-neonbs-glue.c b/arch/arm64/crypto/aes-neonbs-glue.c index 7cb1aede9a48..20b2b23ffa1f 100644 --- a/arch/arm64/crypto/aes-neonbs-glue.c +++ b/arch/arm64/crypto/aes-neonbs-glue.c @@ -247,7 +247,7 @@ static int aesbs_xts_setkey(struct crypto_skcipher *tfm, const u8 *in_key, unsigned int key_len) { struct aesbs_xts_ctx *ctx = crypto_skcipher_ctx(tfm); - struct crypto_aes_ctx rk; + struct crypto_aes_ctx rk __cleanup(aes_zeroize_ctx); int err; err = xts_verify_key(tfm, in_key, key_len); diff --git a/arch/powerpc/crypto/vmx.c b/arch/powerpc/crypto/vmx.c index 08da5311dfdf..8abc4db8ee4e 100644 --- a/arch/powerpc/crypto/vmx.c +++ b/arch/powerpc/crypto/vmx.c @@ -8,12 +8,7 @@ */ #include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/types.h> -#include <linux/err.h> #include <linux/cpufeature.h> -#include <linux/crypto.h> -#include <asm/cputable.h> #include <crypto/internal/skcipher.h> #include "aesp8-ppc.h" @@ -24,7 +19,7 @@ static int __init p8_init(void) ret = crypto_register_skcipher(&p8_aes_cbc_alg); if (ret) - goto err; + return ret; ret = crypto_register_skcipher(&p8_aes_ctr_alg); if (ret) @@ -40,7 +35,6 @@ err_unregister_aes_ctr: crypto_unregister_skcipher(&p8_aes_ctr_alg); err_unregister_aes_cbc: crypto_unregister_skcipher(&p8_aes_cbc_alg); -err: return ret; } @@ -54,8 +48,6 @@ static void __exit p8_exit(void) module_cpu_feature_match(PPC_MODULE_FEATURE_VEC_CRYPTO, p8_init); module_exit(p8_exit); -MODULE_AUTHOR("Marcelo Cerri<mhcerri@br.ibm.com>"); -MODULE_DESCRIPTION("IBM VMX cryptographic acceleration instructions " - "support on Power 8"); +MODULE_AUTHOR("Marcelo Cerri <mhcerri@br.ibm.com>"); +MODULE_DESCRIPTION("IBM VMX cryptographic acceleration instructions support on Power 8"); MODULE_LICENSE("GPL"); -MODULE_VERSION("1.0.0"); diff --git a/crypto/algapi.c b/crypto/algapi.c index 37de377719ae..a6839e2a20f3 100644 --- a/crypto/algapi.c +++ b/crypto/algapi.c @@ -424,7 +424,6 @@ static void crypto_free_alg(struct crypto_alg *alg) unsigned int algsize = alg->cra_type->algsize; u8 *p = (u8 *)alg - algsize; - crypto_destroy_alg(alg); kfree(p); } @@ -494,9 +493,31 @@ void crypto_unregister_alg(struct crypto_alg *alg) LIST_HEAD(list); down_write(&crypto_alg_sem); + if (alg->cra_flags & CRYPTO_ALG_DUP_FIRST) { + struct crypto_alg *q, *r = NULL; + + list_for_each_entry(q, &crypto_alg_list, cra_list) { + if (crypto_is_larval(q)) + continue; + if (strcmp(q->cra_driver_name, alg->cra_driver_name)) + continue; + r = q; + break; + } + + if (!r) { + up_write(&crypto_alg_sem); + ret = -ENOENT; + goto not_found; + } + + alg = r; + } + ret = crypto_remove_alg(alg, &list); up_write(&crypto_alg_sem); +not_found: if (WARN(ret, "Algorithm %s is not registered", alg->cra_driver_name)) return; diff --git a/crypto/algif_hash.c b/crypto/algif_hash.c index 6e8b5fb82a7f..0d3ec5760de6 100644 --- a/crypto/algif_hash.c +++ b/crypto/algif_hash.c @@ -23,7 +23,7 @@ static const struct af_alg_allowlist_entry hash_allowlist[] = { { "hmac(sha224)" }, /* iwd */ { "hmac(sha256)" }, /* iwd */ { "hmac(sha384)" }, /* iwd */ - { "hmac(sha512)" }, /* iwd, sha512hmac */ + { "hmac(sha512)", AF_ALG_UNPRIVILEGED }, /* iwd, sha512hmac */ { "md4" }, /* iwd */ { "md5" }, /* iwd */ { "sha1", AF_ALG_UNPRIVILEGED }, /* iwd, iproute2 < 7.0 */ diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c index 1e61fe6e24b9..291dbd698932 100644 --- a/crypto/algif_skcipher.c +++ b/crypto/algif_skcipher.c @@ -135,12 +135,16 @@ static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg, * full block size buffers. */ if (ctx->more || len < ctx->used) { - if (len < bs) { + size_t excess = len % bs; + + len -= excess; + iov_iter_revert(&msg->msg_iter, excess); + + if (!len) { err = -EINVAL; goto free; } - len -= len % bs; cflags |= CRYPTO_SKCIPHER_REQ_NOTFINAL; } diff --git a/crypto/asymmetric_keys/Kconfig b/crypto/asymmetric_keys/Kconfig index 6a2f664046ef..c73979b2e98e 100644 --- a/crypto/asymmetric_keys/Kconfig +++ b/crypto/asymmetric_keys/Kconfig @@ -114,4 +114,16 @@ config FIPS_SIGNATURE_SELFTEST_ECDSA depends on CRYPTO_SHA256=y || CRYPTO_SHA256=FIPS_SIGNATURE_SELFTEST depends on CRYPTO_ECDSA=y || CRYPTO_ECDSA=FIPS_SIGNATURE_SELFTEST +config VERIFY_PEFILE_KUNIT_TEST + bool "KUnit tests for signed PE file parsing" if !KUNIT_ALL_TESTS + depends on KUNIT=y && SIGNED_PE_FILE_VERIFICATION + default KUNIT_ALL_TESTS + help + Enable KUnit tests for the PE binary parser used by signed PE file + signature verification. The tests build small malformed PE images in + memory and check that pefile_parse_binary() rejects them instead of + reading out of bounds. + + If unsure, say N. + endif # ASYMMETRIC_KEY_TYPE diff --git a/crypto/asymmetric_keys/Makefile b/crypto/asymmetric_keys/Makefile index bc65d3b98dcb..35172685c533 100644 --- a/crypto/asymmetric_keys/Makefile +++ b/crypto/asymmetric_keys/Makefile @@ -79,3 +79,5 @@ verify_signed_pefile-y := \ $(obj)/mscode_parser.o: $(obj)/mscode.asn1.h $(obj)/mscode.asn1.h $(obj)/mscode.asn1.o: $(obj)/mscode.asn1.c $(obj)/mscode.asn1.h + +obj-$(CONFIG_VERIFY_PEFILE_KUNIT_TEST) += verify_pefile_test.o diff --git a/crypto/asymmetric_keys/pkcs7_parser.c b/crypto/asymmetric_keys/pkcs7_parser.c index 6e3ffdac83ac..7f00e45a33cf 100644 --- a/crypto/asymmetric_keys/pkcs7_parser.c +++ b/crypto/asymmetric_keys/pkcs7_parser.c @@ -111,6 +111,12 @@ static int pkcs7_check_authattrs(struct pkcs7_message *msg) if (!!sinfo->authattrs != want) goto inconsistent; +#ifdef CONFIG_PKCS7_WAIVE_AUTHATTRS_REJECTION_FOR_MLDSA + if (sinfo->authattrs && + strncmp(sinfo->sig->pkey_algo, "mldsa", 5) != 0) + msg->authattrs_rej_waivable = false; +#endif + if (!sinfo->authattrs && sinfo->sig->algo_takes_data) sinfo->sig->hash_algo = "none"; diff --git a/crypto/asymmetric_keys/restrict.c b/crypto/asymmetric_keys/restrict.c index 86292965f493..0e4783ff7d22 100644 --- a/crypto/asymmetric_keys/restrict.c +++ b/crypto/asymmetric_keys/restrict.c @@ -243,10 +243,14 @@ static int key_or_keyring_common(struct key *dest_keyring, if (IS_ERR(key)) key = NULL; } else if (trusted->type == &key_type_asymmetric) { + const struct asymmetric_key_ids *kids; const struct asymmetric_key_id **signer_ids; - signer_ids = (const struct asymmetric_key_id **) - asymmetric_key_ids(trusted)->id; + kids = asymmetric_key_ids(trusted); + if (!kids) + return -ENOKEY; + + signer_ids = (const struct asymmetric_key_id **)kids->id; /* * The auth_ids come from the candidate key (the diff --git a/crypto/asymmetric_keys/verify_pefile.c b/crypto/asymmetric_keys/verify_pefile.c index cec99db14129..1efd5c0d0e9c 100644 --- a/crypto/asymmetric_keys/verify_pefile.c +++ b/crypto/asymmetric_keys/verify_pefile.c @@ -87,6 +87,11 @@ static int pefile_parse_binary(const void *pebuf, unsigned int pelen, if (ctx->n_data_dirents > (ctx->header_size - cursor) / sizeof(*dde)) return -ELIBBAD; + /* the certificate table entry must be present in the data directory */ + if (ctx->n_data_dirents <= + offsetof(struct data_directory, certs) / sizeof(*dde)) + return -ELIBBAD; + ddir = pebuf + cursor; cursor += sizeof(*dde) * ctx->n_data_dirents; diff --git a/crypto/asymmetric_keys/verify_pefile_test.c b/crypto/asymmetric_keys/verify_pefile_test.c new file mode 100644 index 000000000000..8b42eb41edd5 --- /dev/null +++ b/crypto/asymmetric_keys/verify_pefile_test.c @@ -0,0 +1,100 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * KUnit tests for the signed PE binary parser in verify_pefile.c. + * + * The cases build small malformed PE images in memory and call + * verify_pefile_signature(), which parses the image before any signature + * check, so the parser is exercised without a keyring or a real signature. + */ +#include <kunit/test.h> +#include <linux/slab.h> +#include <linux/pe.h> +#include <linux/verification.h> + +/* + * Build a minimal PE32 image whose optional header declares @data_dirs data + * directory entries. header_size is sized to hold them and the image is a few + * bytes larger. With @data_dirs < 5 the certificate table entry (fixed index + * 4) lies outside the declared directory. + */ +static void *build_pe32(u16 data_dirs, unsigned int *out_len) +{ + size_t cursor = sizeof(struct mz_hdr) + sizeof(struct pe_hdr) + + sizeof(struct pe32_opt_hdr); + size_t header_size = cursor + ((size_t)data_dirs + 1) * + sizeof(struct data_dirent); + size_t pelen = header_size + 8; + struct mz_hdr *mz; + struct pe_hdr *pe; + struct pe32_opt_hdr *opt; + void *buf = kzalloc(pelen, GFP_KERNEL); + + if (!buf) + return NULL; + + mz = buf; + mz->magic = IMAGE_DOS_SIGNATURE; + mz->peaddr = sizeof(struct mz_hdr); + + pe = buf + sizeof(struct mz_hdr); + pe->magic = IMAGE_NT_SIGNATURE; + + opt = buf + sizeof(struct mz_hdr) + sizeof(struct pe_hdr); + opt->magic = IMAGE_NT_OPTIONAL_HDR32_MAGIC; + opt->header_size = header_size; + opt->data_dirs = data_dirs; + + *out_len = pelen; + return buf; +} + +/* + * data_dirs = 0: the certificate table entry (index 4) is absent, so the + * parser must reject the image instead of reading ddir->certs past the end. + */ +static void pefile_missing_certs_dirent(struct kunit *test) +{ + unsigned int len; + void *buf = build_pe32(0, &len); + int ret; + + KUNIT_ASSERT_NOT_NULL(test, buf); + ret = verify_pefile_signature(buf, len, NULL, + VERIFYING_KEXEC_PE_SIGNATURE); + KUNIT_EXPECT_EQ(test, ret, -ELIBBAD); + kfree(buf); +} + +/* + * data_dirs = 5: the certificate table entry is present (and zero, i.e. + * unsigned), so the parser gets past the directory bound and rejects the image + * as unsigned (-ENODATA) rather than -ELIBBAD. + */ +static void pefile_present_certs_dirent(struct kunit *test) +{ + unsigned int len; + void *buf = build_pe32(5, &len); + int ret; + + KUNIT_ASSERT_NOT_NULL(test, buf); + ret = verify_pefile_signature(buf, len, NULL, + VERIFYING_KEXEC_PE_SIGNATURE); + KUNIT_EXPECT_EQ(test, ret, -ENODATA); + kfree(buf); +} + +static struct kunit_case verify_pefile_cases[] = { + KUNIT_CASE(pefile_missing_certs_dirent), + KUNIT_CASE(pefile_present_certs_dirent), + {} +}; + +static struct kunit_suite verify_pefile_suite = { + .name = "verify_pefile", + .test_cases = verify_pefile_cases, +}; + +kunit_test_suite(verify_pefile_suite); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("KUnit tests for the signed PE binary parser"); diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c index 25cf8ac7f257..5c9165a83f91 100644 --- a/crypto/asymmetric_keys/x509_public_key.c +++ b/crypto/asymmetric_keys/x509_public_key.c @@ -53,9 +53,11 @@ int x509_get_sig_params(struct x509_certificate *cert) if (sig->algo_takes_data) { /* The signature algorithm does whatever passes for hashing. */ - sig->m = (u8 *)cert->tbs; + sig->m = kmemdup(cert->tbs, cert->tbs_size, GFP_KERNEL); + if (!sig->m) + return -ENOMEM; sig->m_size = cert->tbs_size; - sig->m_free = false; + sig->m_free = true; goto out; } diff --git a/crypto/cast5_generic.c b/crypto/cast5_generic.c index f68330793e0c..1de0dc966a03 100644 --- a/crypto/cast5_generic.c +++ b/crypto/cast5_generic.c @@ -483,9 +483,7 @@ int cast5_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int key_len) c->rr = key_len <= 10 ? 1 : 0; - memset(p_key, 0, 16); - memcpy(p_key, key, key_len); - + memcpy_and_pad(p_key, sizeof(p_key), key, key_len, 0); x[0] = be32_to_cpu(p_key[0]); x[1] = be32_to_cpu(p_key[1]); diff --git a/crypto/cast6_generic.c b/crypto/cast6_generic.c index 4c08c42646f0..9b6bdd2aa511 100644 --- a/crypto/cast6_generic.c +++ b/crypto/cast6_generic.c @@ -112,8 +112,7 @@ int __cast6_setkey(struct cast6_ctx *c, const u8 *in_key, unsigned int key_len) if (key_len % 4 != 0) return -EINVAL; - memset(p_key, 0, 32); - memcpy(p_key, in_key, key_len); + memcpy_and_pad(p_key, sizeof(p_key), in_key, key_len, 0); key[0] = be32_to_cpu(p_key[0]); /* A */ key[1] = be32_to_cpu(p_key[1]); /* B */ diff --git a/crypto/ecc.c b/crypto/ecc.c index 3250a464b852..c7366eb7ce1f 100644 --- a/crypto/ecc.c +++ b/crypto/ecc.c @@ -1423,9 +1423,22 @@ static void ecc_point_add(const struct ecc_point *result, vli_set(result->x, q->x, ndigits); vli_set(result->y, q->y, ndigits); vli_mod_sub(z, result->x, p->x, curve->p, ndigits); + if (vli_is_zero(z, ndigits)) { + if (vli_cmp(p->y, q->y, ndigits)) { + /* P + (-P) is the point at infinity. */ + vli_clear(result->x, ndigits); + vli_clear(result->y, ndigits); + return; + } + /* The co-Z addition formula does not handle P == Q. */ + z[0] = 1; + ecc_point_double_jacobian(result->x, result->y, z, curve); + goto out; + } vli_set(px, p->x, ndigits); vli_set(py, p->y, ndigits); xycz_add(px, py, result->x, result->y, curve); +out: vli_mod_inv(z, z, curve->p, ndigits); apply_z(result->x, result->y, z, curve); } @@ -1465,22 +1478,38 @@ void ecc_point_mult_shamir(const struct ecc_point *result, vli_set(rx, point->x, ndigits); vli_set(ry, point->y, ndigits); vli_clear(z + 1, ndigits - 1); - z[0] = 1; + z[0] = !ecc_point_is_zero(point); for (--i; i >= 0; i--) { ecc_point_double_jacobian(rx, ry, z, curve); idx = !!vli_test_bit(u1, i); idx |= (!!vli_test_bit(u2, i)) << 1; point = points[idx]; - if (point) { + if (point && !ecc_point_is_zero(point)) { u64 tx[ECC_MAX_DIGITS]; u64 ty[ECC_MAX_DIGITS]; u64 tz[ECC_MAX_DIGITS]; + if (vli_is_zero(z, ndigits)) { + /* Adding to infinity starts a new accumulator. */ + vli_set(rx, point->x, ndigits); + vli_set(ry, point->y, ndigits); + z[0] = 1; + continue; + } vli_set(tx, point->x, ndigits); vli_set(ty, point->y, ndigits); apply_z(tx, ty, z, curve); vli_mod_sub(tz, rx, tx, curve->p, ndigits); + if (vli_is_zero(tz, ndigits)) { + if (!vli_cmp(ry, ty, ndigits)) + ecc_point_double_jacobian(rx, ry, z, + curve); + else + /* Adding opposite points yields infinity. */ + vli_clear(z, ndigits); + continue; + } xycz_add(tx, ty, rx, ry, curve); vli_mod_mult_fast(z, z, tz, curve); } diff --git a/crypto/lskcipher.c b/crypto/lskcipher.c index a8b07594005d..6c30436a1135 100644 --- a/crypto/lskcipher.c +++ b/crypto/lskcipher.c @@ -75,6 +75,7 @@ static int crypto_lskcipher_crypt_unaligned( unsigned ivsize = crypto_lskcipher_ivsize(tfm); unsigned bs = crypto_lskcipher_blocksize(tfm); unsigned cs = crypto_lskcipher_chunksize(tfm); + u32 flags = 0; int err; u8 *tiv; u8 *p; @@ -98,13 +99,16 @@ static int crypto_lskcipher_crypt_unaligned( if (chunk > cs) chunk &= ~(cs - 1); + if (chunk == len) + flags |= CRYPTO_LSKCIPHER_FLAG_FINAL; memcpy(p, src, chunk); - err = crypt(tfm, p, p, chunk, tiv, CRYPTO_LSKCIPHER_FLAG_FINAL); + err = crypt(tfm, p, p, chunk, tiv, flags); if (err) goto out; memcpy(dst, p, chunk); + flags |= CRYPTO_LSKCIPHER_FLAG_CONT; src += chunk; dst += chunk; len -= chunk; diff --git a/crypto/rsassa-pkcs1.c b/crypto/rsassa-pkcs1.c index 94fa5e9600e7..39137476ce81 100644 --- a/crypto/rsassa-pkcs1.c +++ b/crypto/rsassa-pkcs1.c @@ -169,7 +169,7 @@ static int rsassa_pkcs1_sign(struct crypto_sig *tfm, u8 *in_buf; int err; - if (!ctx->key_size) + if (ctx->key_size < 11) return -EINVAL; if (dlen < ctx->key_size) @@ -231,7 +231,7 @@ static int rsassa_pkcs1_verify(struct crypto_sig *tfm, int err; /* RFC 8017 sec 8.2.2 step 1 - length checking */ - if (!ctx->key_size || + if (ctx->key_size < 11 || slen != ctx->key_size || rsassa_pkcs1_invalid_hash_len(dlen, hash_prefix)) return -EINVAL; diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index 61a2501bfe9b..e6834bdde9b9 100644 --- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c @@ -56,6 +56,21 @@ */ #define get_driver_name(tfm_type, tfm) crypto_tfm_alg_driver_name(tfm_type ## _tfm(tfm)) +struct tcrypt_aead_request { + struct aead_request *req; + struct crypto_wait wait; +}; + +struct tcrypt_ahash_request { + struct ahash_request *req; + struct crypto_wait wait; +}; + +struct tcrypt_skcipher_request { + struct skcipher_request *req; + struct crypto_wait wait; +}; + /* * Used by test_cipher_speed() */ @@ -129,18 +144,15 @@ static void sg_init_aead(struct scatterlist *sg, char *xbuf[XBUFSIZE], sg_set_buf(&sg[k + 1], xbuf[k], rem); } -static inline int do_one_aead_op(struct aead_request *req, int ret) +static inline int do_one_aead_op(struct tcrypt_aead_request *req, int ret) { - struct crypto_wait *wait = req->base.data; - - return crypto_wait_req(ret, wait); + return crypto_wait_req(ret, &req->wait); } struct test_mb_aead_data { struct scatterlist sg[XBUFSIZE]; struct scatterlist sgout[XBUFSIZE]; - struct aead_request *req; - struct crypto_wait wait; + struct tcrypt_aead_request req; char *xbuf[XBUFSIZE]; char *xoutbuf[XBUFSIZE]; char *axbuf[XBUFSIZE]; @@ -154,14 +166,14 @@ static int do_mult_aead_op(struct test_mb_aead_data *data, int enc, /* Fire up a bunch of concurrent requests */ for (i = 0; i < num_mb; i++) { if (enc == ENCRYPT) - rc[i] = crypto_aead_encrypt(data[i].req); + rc[i] = crypto_aead_encrypt(data[i].req.req); else - rc[i] = crypto_aead_decrypt(data[i].req); + rc[i] = crypto_aead_decrypt(data[i].req.req); } /* Wait for all requests to finish */ for (i = 0; i < num_mb; i++) { - rc[i] = crypto_wait_req(rc[i], &data[i].wait); + rc[i] = crypto_wait_req(rc[i], &data[i].req.wait); if (rc[i]) { pr_info("concurrent request %d error %d\n", i, rc[i]); @@ -310,21 +322,21 @@ static void test_mb_aead_speed(const char *algo, int enc, int secs, } for (i = 0; i < num_mb; ++i) { - data[i].req = aead_request_alloc(tfm, GFP_KERNEL); - if (!data[i].req) { + data[i].req.req = aead_request_alloc(tfm, GFP_KERNEL); + if (!data[i].req.req) { pr_err("alg: aead: Failed to allocate request for %s\n", algo); while (i--) - aead_request_free(data[i].req); + aead_request_free(data[i].req.req); goto out_free_xoutbuf; } } for (i = 0; i < num_mb; ++i) { - crypto_init_wait(&data[i].wait); - aead_request_set_callback(data[i].req, + crypto_init_wait(&data[i].req.wait); + aead_request_set_callback(data[i].req.req, CRYPTO_TFM_REQ_MAY_BACKLOG, - crypto_req_done, &data[i].wait); + crypto_req_done, &data[i].req.wait); } pr_info("testing speed of multibuffer %s (%s) %s\n", algo, @@ -386,16 +398,16 @@ static void test_mb_aead_speed(const char *algo, int enc, int secs, bs + (enc ? authsize : 0), assoc, aad_size); - aead_request_set_ad(cur->req, aad_size); + aead_request_set_ad(cur->req.req, aad_size); if (!enc) { - aead_request_set_crypt(cur->req, + aead_request_set_crypt(cur->req.req, cur->sgout, cur->sg, bs, iv); - ret = crypto_aead_encrypt(cur->req); - ret = do_one_aead_op(cur->req, ret); + ret = crypto_aead_encrypt(cur->req.req); + ret = do_one_aead_op(&cur->req, ret); if (ret) { pr_err("calculating auth failed (%d)\n", @@ -404,7 +416,7 @@ static void test_mb_aead_speed(const char *algo, int enc, int secs, } } - aead_request_set_crypt(cur->req, cur->sg, + aead_request_set_crypt(cur->req.req, cur->sg, cur->sgout, bs + (enc ? 0 : authsize), iv); @@ -432,7 +444,7 @@ static void test_mb_aead_speed(const char *algo, int enc, int secs, out: for (i = 0; i < num_mb; ++i) - aead_request_free(data[i].req); + aead_request_free(data[i].req.req); out_free_xoutbuf: for (i = 0; i < num_mb; ++i) testmgr_free_buf(data[i].xoutbuf); @@ -450,9 +462,10 @@ out_free_iv: kfree(iv); } -static int test_aead_jiffies(struct aead_request *req, int enc, +static int test_aead_jiffies(struct tcrypt_aead_request *treq, int enc, int blen, int secs) { + struct aead_request *req = treq->req; unsigned long start, end; int bcount; int ret; @@ -460,9 +473,9 @@ static int test_aead_jiffies(struct aead_request *req, int enc, for (start = jiffies, end = start + secs * HZ, bcount = 0; time_before(jiffies, end); bcount++) { if (enc) - ret = do_one_aead_op(req, crypto_aead_encrypt(req)); + ret = do_one_aead_op(treq, crypto_aead_encrypt(req)); else - ret = do_one_aead_op(req, crypto_aead_decrypt(req)); + ret = do_one_aead_op(treq, crypto_aead_decrypt(req)); if (ret) return ret; @@ -473,8 +486,9 @@ static int test_aead_jiffies(struct aead_request *req, int enc, return 0; } -static int test_aead_cycles(struct aead_request *req, int enc, int blen) +static int test_aead_cycles(struct tcrypt_aead_request *treq, int enc, int blen) { + struct aead_request *req = treq->req; unsigned long cycles = 0; int ret = 0; int i; @@ -482,9 +496,9 @@ static int test_aead_cycles(struct aead_request *req, int enc, int blen) /* Warm-up run. */ for (i = 0; i < 4; i++) { if (enc) - ret = do_one_aead_op(req, crypto_aead_encrypt(req)); + ret = do_one_aead_op(treq, crypto_aead_encrypt(req)); else - ret = do_one_aead_op(req, crypto_aead_decrypt(req)); + ret = do_one_aead_op(treq, crypto_aead_decrypt(req)); if (ret) goto out; @@ -496,9 +510,9 @@ static int test_aead_cycles(struct aead_request *req, int enc, int blen) start = get_cycles(); if (enc) - ret = do_one_aead_op(req, crypto_aead_encrypt(req)); + ret = do_one_aead_op(treq, crypto_aead_encrypt(req)); else - ret = do_one_aead_op(req, crypto_aead_decrypt(req)); + ret = do_one_aead_op(treq, crypto_aead_decrypt(req)); end = get_cycles(); if (ret) @@ -520,6 +534,7 @@ static void test_aead_speed(const char *algo, int enc, unsigned int secs, unsigned int tcount, u8 authsize, unsigned int aad_size, u8 *keysize) { + struct tcrypt_aead_request treq; unsigned int i, j; struct crypto_aead *tfm; int ret = -ENOMEM; @@ -535,7 +550,6 @@ static void test_aead_speed(const char *algo, int enc, unsigned int secs, char *axbuf[XBUFSIZE]; const int *b_size; unsigned int iv_len; - struct crypto_wait wait; iv = kzalloc(MAX_IVLEN, GFP_KERNEL); if (!iv) @@ -577,7 +591,7 @@ static void test_aead_speed(const char *algo, int enc, unsigned int secs, goto out_noreq; } - crypto_init_wait(&wait); + crypto_init_wait(&treq.wait); pr_info("testing speed of %s (%s) %s\n", algo, get_driver_name(crypto_aead, tfm), e); @@ -587,9 +601,10 @@ static void test_aead_speed(const char *algo, int enc, unsigned int secs, algo); goto out_noreq; } + treq.req = req; aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, - crypto_req_done, &wait); + crypto_req_done, &treq.wait); i = 0; do { @@ -650,7 +665,7 @@ static void test_aead_speed(const char *algo, int enc, unsigned int secs, */ aead_request_set_crypt(req, sgout, sg, bs, iv); - ret = do_one_aead_op(req, + ret = do_one_aead_op(&treq, crypto_aead_encrypt(req)); if (ret) { @@ -665,11 +680,11 @@ static void test_aead_speed(const char *algo, int enc, unsigned int secs, iv); if (secs) { - ret = test_aead_jiffies(req, enc, bs, + ret = test_aead_jiffies(&treq, enc, bs, secs); cond_resched(); } else { - ret = test_aead_cycles(req, enc, bs); + ret = test_aead_cycles(&treq, enc, bs); } if (ret) { @@ -709,23 +724,22 @@ static void test_hash_sg_init(struct scatterlist *sg) } } -static inline int do_one_ahash_op(struct ahash_request *req, int ret) +static inline int do_one_ahash_op(struct tcrypt_ahash_request *treq, int ret) { - struct crypto_wait *wait = req->base.data; - - return crypto_wait_req(ret, wait); + return crypto_wait_req(ret, &treq->wait); } -static int test_ahash_jiffies_digest(struct ahash_request *req, int blen, - char *out, int secs) +static int test_ahash_jiffies_digest(struct tcrypt_ahash_request *treq, + int blen, char *out, int secs) { + struct ahash_request *req = treq->req; unsigned long start, end; int bcount; int ret; for (start = jiffies, end = start + secs * HZ, bcount = 0; time_before(jiffies, end); bcount++) { - ret = do_one_ahash_op(req, crypto_ahash_digest(req)); + ret = do_one_ahash_op(treq, crypto_ahash_digest(req)); if (ret) return ret; } @@ -736,28 +750,29 @@ static int test_ahash_jiffies_digest(struct ahash_request *req, int blen, return 0; } -static int test_ahash_jiffies(struct ahash_request *req, int blen, +static int test_ahash_jiffies(struct tcrypt_ahash_request *treq, int blen, int plen, char *out, int secs) { + struct ahash_request *req = treq->req; unsigned long start, end; int bcount, pcount; int ret; if (plen == blen) - return test_ahash_jiffies_digest(req, blen, out, secs); + return test_ahash_jiffies_digest(treq, blen, out, secs); for (start = jiffies, end = start + secs * HZ, bcount = 0; time_before(jiffies, end); bcount++) { - ret = do_one_ahash_op(req, crypto_ahash_init(req)); + ret = do_one_ahash_op(treq, crypto_ahash_init(req)); if (ret) return ret; for (pcount = 0; pcount < blen; pcount += plen) { - ret = do_one_ahash_op(req, crypto_ahash_update(req)); + ret = do_one_ahash_op(treq, crypto_ahash_update(req)); if (ret) return ret; } /* we assume there is enough space in 'out' for the result */ - ret = do_one_ahash_op(req, crypto_ahash_final(req)); + ret = do_one_ahash_op(treq, crypto_ahash_final(req)); if (ret) return ret; } @@ -768,15 +783,16 @@ static int test_ahash_jiffies(struct ahash_request *req, int blen, return 0; } -static int test_ahash_cycles_digest(struct ahash_request *req, int blen, - char *out) +static int test_ahash_cycles_digest(struct tcrypt_ahash_request *treq, + int blen, char *out) { + struct ahash_request *req = treq->req; unsigned long cycles = 0; int ret, i; /* Warm-up run. */ for (i = 0; i < 4; i++) { - ret = do_one_ahash_op(req, crypto_ahash_digest(req)); + ret = do_one_ahash_op(treq, crypto_ahash_digest(req)); if (ret) goto out; } @@ -787,7 +803,7 @@ static int test_ahash_cycles_digest(struct ahash_request *req, int blen, start = get_cycles(); - ret = do_one_ahash_op(req, crypto_ahash_digest(req)); + ret = do_one_ahash_op(treq, crypto_ahash_digest(req)); if (ret) goto out; @@ -806,26 +822,27 @@ out: return 0; } -static int test_ahash_cycles(struct ahash_request *req, int blen, +static int test_ahash_cycles(struct tcrypt_ahash_request *treq, int blen, int plen, char *out) { + struct ahash_request *req = treq->req; unsigned long cycles = 0; int i, pcount, ret; if (plen == blen) - return test_ahash_cycles_digest(req, blen, out); + return test_ahash_cycles_digest(treq, blen, out); /* Warm-up run. */ for (i = 0; i < 4; i++) { - ret = do_one_ahash_op(req, crypto_ahash_init(req)); + ret = do_one_ahash_op(treq, crypto_ahash_init(req)); if (ret) goto out; for (pcount = 0; pcount < blen; pcount += plen) { - ret = do_one_ahash_op(req, crypto_ahash_update(req)); + ret = do_one_ahash_op(treq, crypto_ahash_update(req)); if (ret) goto out; } - ret = do_one_ahash_op(req, crypto_ahash_final(req)); + ret = do_one_ahash_op(treq, crypto_ahash_final(req)); if (ret) goto out; } @@ -836,15 +853,15 @@ static int test_ahash_cycles(struct ahash_request *req, int blen, start = get_cycles(); - ret = do_one_ahash_op(req, crypto_ahash_init(req)); + ret = do_one_ahash_op(treq, crypto_ahash_init(req)); if (ret) goto out; for (pcount = 0; pcount < blen; pcount += plen) { - ret = do_one_ahash_op(req, crypto_ahash_update(req)); + ret = do_one_ahash_op(treq, crypto_ahash_update(req)); if (ret) goto out; } - ret = do_one_ahash_op(req, crypto_ahash_final(req)); + ret = do_one_ahash_op(treq, crypto_ahash_final(req)); if (ret) goto out; @@ -867,7 +884,7 @@ static void test_ahash_speed_common(const char *algo, unsigned int secs, struct hash_speed *speed, unsigned mask) { struct scatterlist sg[TVMEMSIZE]; - struct crypto_wait wait; + struct tcrypt_ahash_request treq; struct ahash_request *req; struct crypto_ahash *tfm; char *output; @@ -896,9 +913,10 @@ static void test_ahash_speed_common(const char *algo, unsigned int secs, goto out; } - crypto_init_wait(&wait); + treq.req = req; + crypto_init_wait(&treq.wait); ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, - crypto_req_done, &wait); + crypto_req_done, &treq.wait); output = kmalloc(MAX_DIGEST_SIZE, GFP_KERNEL); if (!output) @@ -927,11 +945,11 @@ static void test_ahash_speed_common(const char *algo, unsigned int secs, ahash_request_set_crypt(req, sg, output, speed[i].plen); if (secs) { - ret = test_ahash_jiffies(req, speed[i].blen, + ret = test_ahash_jiffies(&treq, speed[i].blen, speed[i].plen, output, secs); cond_resched(); } else { - ret = test_ahash_cycles(req, speed[i].blen, + ret = test_ahash_cycles(&treq, speed[i].blen, speed[i].plen, output); } @@ -1217,16 +1235,16 @@ out_free_data: kfree(data); } -static inline int do_one_acipher_op(struct skcipher_request *req, int ret) +static inline int do_one_acipher_op(struct tcrypt_skcipher_request *req, + int ret) { - struct crypto_wait *wait = req->base.data; - - return crypto_wait_req(ret, wait); + return crypto_wait_req(ret, &req->wait); } -static int test_acipher_jiffies(struct skcipher_request *req, int enc, +static int test_acipher_jiffies(struct tcrypt_skcipher_request *treq, int enc, int blen, int secs) { + struct skcipher_request *req = treq->req; unsigned long start, end; int bcount; int ret; @@ -1234,10 +1252,10 @@ static int test_acipher_jiffies(struct skcipher_request *req, int enc, for (start = jiffies, end = start + secs * HZ, bcount = 0; time_before(jiffies, end); bcount++) { if (enc) - ret = do_one_acipher_op(req, + ret = do_one_acipher_op(treq, crypto_skcipher_encrypt(req)); else - ret = do_one_acipher_op(req, + ret = do_one_acipher_op(treq, crypto_skcipher_decrypt(req)); if (ret) @@ -1249,9 +1267,10 @@ static int test_acipher_jiffies(struct skcipher_request *req, int enc, return 0; } -static int test_acipher_cycles(struct skcipher_request *req, int enc, +static int test_acipher_cycles(struct tcrypt_skcipher_request *treq, int enc, int blen) { + struct skcipher_request *req = treq->req; unsigned long cycles = 0; int ret = 0; int i; @@ -1259,10 +1278,10 @@ static int test_acipher_cycles(struct skcipher_request *req, int enc, /* Warm-up run. */ for (i = 0; i < 4; i++) { if (enc) - ret = do_one_acipher_op(req, + ret = do_one_acipher_op(treq, crypto_skcipher_encrypt(req)); else - ret = do_one_acipher_op(req, + ret = do_one_acipher_op(treq, crypto_skcipher_decrypt(req)); if (ret) @@ -1275,10 +1294,10 @@ static int test_acipher_cycles(struct skcipher_request *req, int enc, start = get_cycles(); if (enc) - ret = do_one_acipher_op(req, + ret = do_one_acipher_op(treq, crypto_skcipher_encrypt(req)); else - ret = do_one_acipher_op(req, + ret = do_one_acipher_op(treq, crypto_skcipher_decrypt(req)); end = get_cycles(); @@ -1300,8 +1319,8 @@ static void test_skcipher_speed(const char *algo, int enc, unsigned int secs, struct cipher_speed_template *template, unsigned int tcount, u8 *keysize, bool async) { + struct tcrypt_skcipher_request treq; unsigned int ret, i, j, k, iv_len; - struct crypto_wait wait; const char *key; char iv[128]; struct skcipher_request *req; @@ -1314,7 +1333,7 @@ static void test_skcipher_speed(const char *algo, int enc, unsigned int secs, else e = "decryption"; - crypto_init_wait(&wait); + crypto_init_wait(&treq.wait); tfm = crypto_alloc_skcipher(algo, 0, async ? 0 : CRYPTO_ALG_ASYNC); @@ -1333,8 +1352,9 @@ static void test_skcipher_speed(const char *algo, int enc, unsigned int secs, goto out; } + treq.req = req; skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, - crypto_req_done, &wait); + crypto_req_done, &treq.wait); i = 0; do { @@ -1401,11 +1421,11 @@ static void test_skcipher_speed(const char *algo, int enc, unsigned int secs, skcipher_request_set_crypt(req, sg, sg, bs, iv); if (secs) { - ret = test_acipher_jiffies(req, enc, + ret = test_acipher_jiffies(&treq, enc, bs, secs); cond_resched(); } else { - ret = test_acipher_cycles(req, enc, + ret = test_acipher_cycles(&treq, enc, bs); } diff --git a/crypto/testmgr.c b/crypto/testmgr.c index 4958211fbfa9..9419d61d0602 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c @@ -3958,16 +3958,17 @@ static int test_sig_one(struct crypto_sig *tfm, const struct sig_testvec *vecs) */ err = crypto_sig_verify(tfm, vecs->c, vecs->c_size, vecs->m, vecs->m_size); - if (err) { - pr_err("alg: sig: verify test failed: err %d\n", err); - return err; + if (err != vecs->verify_error) { + pr_err("alg: sig: verify test failed: expected %d, got %d\n", + vecs->verify_error, err); + return err ?: -EINVAL; } /* * Don't invoke sign test (which requires a private key) - * for vectors with only a public key. + * for vectors with only a public key or an invalid signature. */ - if (vecs->public_key_vec) + if (vecs->public_key_vec || vecs->verify_error) return 0; sig_size = crypto_sig_maxsize(tfm); diff --git a/crypto/testmgr.h b/crypto/testmgr.h index c4a15e714ecd..0ee15a8fae27 100644 --- a/crypto/testmgr.h +++ b/crypto/testmgr.h @@ -161,6 +161,7 @@ struct sig_testvec { unsigned int param_len; unsigned int m_size; unsigned int c_size; + int verify_error; bool public_key_vec; enum OID algo; }; @@ -1443,6 +1444,140 @@ static const struct sig_testvec x962_ecdsa_nist_p192_tv_template[] = { }; static const struct sig_testvec x962_ecdsa_nist_p256_tv_template[] = { + /* Invalid signature: Q = G, r = s, e = 3r mod n. */ + { + .key = + "\x04\x6b\x17\xd1\xf2\xe1\x2c\x42\x47\xf8\xbc\xe6\xe5\x63\xa4\x40" + "\xf2\x77\x03\x7d\x81\x2d\xeb\x33\xa0\xf4\xa1\x39\x45\xd8\x98\xc2" + "\x96\x4f\xe3\x42\xe2\xfe\x1a\x7f\x9b\x8e\xe7\xeb\x4a\x7c\x0f\x9e" + "\x16\x2b\xce\x33\x57\x6b\x31\x5e\xce\xcb\xb6\x40\x68\x37\xbf\x51" + "\xf5", + .key_len = 65, + .m = + "\xb2\xc3\x09\x72\x03\x17\x9d\xaa\x5c\x4a\xd8\xff\x02\xfe\xcb\x15" + "\x21\x53\x81\x77\x45\xec\x45\x24\x3d\x68\x10\xb9\xf2\xa5\x88\x3a", + .m_size = 32, + .c = + "\x30\x46\x02\x21\x00\x90\xeb\xad\xd0\x56\x5d\x34\x8e\x74\x18\xf2" + "\xff\xab\xaa\x43\xb1\x9f\x68\xd4\x0c\x4f\x01\x4b\xe3\x10\x60\x9e" + "\x7e\xfa\x58\x39\xd9\x02\x21\x00\x90\xeb\xad\xd0\x56\x5d\x34\x8e" + "\x74\x18\xf2\xff\xab\xaa\x43\xb1\x9f\x68\xd4\x0c\x4f\x01\x4b\xe3" + "\x10\x60\x9e\x7e\xfa\x58\x39\xd9", + .c_size = 72, + .verify_error = -EKEYREJECTED, + .public_key_vec = true, + }, + /* Invalid signature: Q = -G, r = s, e = 3r mod n. */ + { + .key = + "\x04\x6b\x17\xd1\xf2\xe1\x2c\x42\x47\xf8\xbc\xe6\xe5\x63\xa4\x40" + "\xf2\x77\x03\x7d\x81\x2d\xeb\x33\xa0\xf4\xa1\x39\x45\xd8\x98\xc2" + "\x96\xb0\x1c\xbd\x1c\x01\xe5\x80\x65\x71\x18\x14\xb5\x83\xf0\x61" + "\xe9\xd4\x31\xcc\xa9\x94\xce\xa1\x31\x34\x49\xbf\x97\xc8\x40\xae" + "\x0a", + .key_len = 65, + .m = + "\xb2\xc3\x09\x72\x03\x17\x9d\xaa\x5c\x4a\xd8\xff\x02\xfe\xcb\x15" + "\x21\x53\x81\x77\x45\xec\x45\x24\x3d\x68\x10\xb9\xf2\xa5\x88\x3a", + .m_size = 32, + .c = + "\x30\x46\x02\x21\x00\x90\xeb\xad\xd0\x56\x5d\x34\x8e\x74\x18\xf2" + "\xff\xab\xaa\x43\xb1\x9f\x68\xd4\x0c\x4f\x01\x4b\xe3\x10\x60\x9e" + "\x7e\xfa\x58\x39\xd9\x02\x21\x00\x90\xeb\xad\xd0\x56\x5d\x34\x8e" + "\x74\x18\xf2\xff\xab\xaa\x43\xb1\x9f\x68\xd4\x0c\x4f\x01\x4b\xe3" + "\x10\x60\x9e\x7e\xfa\x58\x39\xd9", + .c_size = 72, + .verify_error = -EKEYREJECTED, + .public_key_vec = true, + }, + /* Wycheproof secp256r1/SHA-256 tcId 60. */ + { + .key = + "\x04\x29\x27\xb1\x05\x12\xba\xe3\xed\xdc\xfe\x46\x78\x28\x12\x8b" + "\xad\x29\x03\x26\x99\x19\xf7\x08\x60\x69\xc8\xc4\xdf\x6c\x73\x28" + "\x38\xc7\x78\x79\x64\xea\xac\x00\xe5\x92\x1f\xb1\x49\x8a\x60\xf4" + "\x60\x67\x66\xb3\xd9\x68\x50\x01\x55\x8d\x1a\x97\x4e\x73\x41\x51" + "\x3e", + .key_len = 65, + .m = + "\x70\x23\x9d\xd8\x77\xf7\xc9\x44\xc4\x22\xf4\x4d\xea\x4e\xd1\xa5" + "\x2f\x26\x27\x41\x6f\xaf\x2f\x07\x2f\xa5\x0c\x77\x2e\xd6\xf8\x07", + .m_size = 32, + .c = + "\x30\x44\x02\x20\x64\xa1\xaa\xb5\x00\x0d\x0e\x80\x4f\x3e\x2f\xc0" + "\x2b\xde\xe9\xbe\x8f\xf3\x12\x33\x4e\x2b\xa1\x6d\x11\x54\x7c\x97" + "\x71\x1c\x89\x8e\x02\x20\x6a\xf0\x15\x97\x1c\xc3\x0b\xe6\xd1\xa2" + "\x06\xd4\xe0\x13\xe0\x99\x77\x72\xa2\xf9\x1d\x73\x28\x6f\xfd\x68" + "\x3b\x9b\xb2\xcf\x4f\x1b", + .c_size = 70, + .public_key_vec = true, + }, + /* Wycheproof secp256r1/SHA-256 tcId 210. */ + { + .key = + "\x04\xc6\xa7\x71\x52\x70\x24\x22\x77\x92\x17\x0a\x6f\x8e\xee\x73" + "\x5b\xf3\x2b\x7f\x98\xaf\x66\x9e\xad\x29\x98\x02\xe3\x2d\x7c\x31" + "\x07\xbc\x3b\x4b\x5e\x65\xab\x88\x7b\xbd\x34\x35\x72\xb3\xe5\x61" + "\x92\x61\xfe\x3a\x07\x3e\x2f\xfd\x78\x41\x2f\x72\x68\x67\xdb\x58" + "\x9e", + .key_len = 65, + .m = + "\xbb\x5a\x52\xf4\x2f\x9c\x92\x61\xed\x43\x61\xf5\x94\x22\xa1\xe3" + "\x00\x36\xe7\xc3\x2b\x27\x0c\x88\x07\xa4\x19\xfe\xca\x60\x50\x23", + .m_size = 32, + .c = + "\x30\x45\x02\x20\x7c\xf2\x7b\x18\x8d\x03\x4f\x7e\x8a\x52\x38\x03" + "\x04\xb5\x1a\xc3\xc0\x89\x69\xe2\x77\xf2\x1b\x35\xa6\x0b\x48\xfc" + "\x47\x66\x99\x78\x02\x21\x00\xb6\xdb\x6d\xb6\x24\x92\x49\x25\x49" + "\x24\x92\x49\x24\x92\x49\x24\x62\x5b\xd7\xa0\x9b\xec\x4c\xa8\x1b" + "\xcd\xd9\xf8\xfd\x6b\x63\xcc", + .c_size = 71, + .public_key_vec = true, + }, + /* Q = G, d = 1, k = 2. */ + { + .key = + "\x04\x6b\x17\xd1\xf2\xe1\x2c\x42\x47\xf8\xbc\xe6\xe5\x63\xa4\x40" + "\xf2\x77\x03\x7d\x81\x2d\xeb\x33\xa0\xf4\xa1\x39\x45\xd8\x98\xc2" + "\x96\x4f\xe3\x42\xe2\xfe\x1a\x7f\x9b\x8e\xe7\xeb\x4a\x7c\x0f\x9e" + "\x16\x2b\xce\x33\x57\x6b\x31\x5e\xce\xcb\xb6\x40\x68\x37\xbf\x51" + "\xf5", + .key_len = 65, + .m = + "\x35\x9d\x17\x29\xb9\x1a\x52\xe9\x8b\xb5\x95\xc3\x86\x28\x3c\x10" + "\x30\x44\x95\x1a\xa1\x08\x20\xf0\xa0\x22\xc4\x18\xc2\x71\xa0\xcc", + .m_size = 32, + .c = + "\x30\x44\x02\x20\x7c\xf2\x7b\x18\x8d\x03\x4f\x7e\x8a\x52\x38\x03" + "\x04\xb5\x1a\xc3\xc0\x89\x69\xe2\x77\xf2\x1b\x35\xa6\x0b\x48\xfc" + "\x47\x66\x99\x78\x02\x20\x59\x47\xc9\x21\x23\x0e\xd1\x34\x0b\x03" + "\xe6\xe3\x45\x6e\xab\x69\xf8\x66\xff\x7e\x8c\x7d\x1e\x13\x23\x17" + "\x06\x8a\x84\xec\x1d\x22", + .c_size = 70, + .public_key_vec = true, + }, + /* Q = -G, d = n - 1, k = 2. */ + { + .key = + "\x04\x6b\x17\xd1\xf2\xe1\x2c\x42\x47\xf8\xbc\xe6\xe5\x63\xa4\x40" + "\xf2\x77\x03\x7d\x81\x2d\xeb\x33\xa0\xf4\xa1\x39\x45\xd8\x98\xc2" + "\x96\xb0\x1c\xbd\x1c\x01\xe5\x80\x65\x71\x18\x14\xb5\x83\xf0\x61" + "\xe9\xd4\x31\xcc\xa9\x94\xce\xa1\x31\x34\x49\xbf\x97\xc8\x40\xae" + "\x0a", + .key_len = 65, + .m = + "\x35\x9d\x17\x29\xb9\x1a\x52\xe9\x8b\xb5\x95\xc3\x86\x28\x3c\x10" + "\x30\x44\x95\x1a\xa1\x08\x20\xf0\xa0\x22\xc4\x18\xc2\x71\xa0\xcc", + .m_size = 32, + .c = + "\x30\x45\x02\x20\x7c\xf2\x7b\x18\x8d\x03\x4f\x7e\x8a\x52\x38\x03" + "\x04\xb5\x1a\xc3\xc0\x89\x69\xe2\x77\xf2\x1b\x35\xa6\x0b\x48\xfc" + "\x47\x66\x99\x78\x02\x21\x00\xdc\x55\x4e\x07\x96\x0b\x81\xb6\x80" + "\xb1\xae\xe0\x40\xb9\x90\xa5\xf4\xc4\x90\x49\xbb\xa2\xa1\x62\x70" + "\xc5\x88\x51\x39\xe8\xa8\xfb", + .c_size = 71, + .public_key_vec = true, + }, { .key = /* secp256r1(sha1) */ "\x04\xb9\x7b\xbb\xd7\x17\x64\xd2\x7e\xfc\x81\x5d\x87\x06\x83\x41" @@ -1827,7 +1962,8 @@ static const struct sig_testvec p1363_ecdsa_nist_p256_tv_template[] = { }; /* - * EC-RDSA test vectors are generated by gost-engine. + * EC-RDSA test vectors generated by gost-engine, followed by constructed + * exceptional-point regression vectors. */ static const struct sig_testvec ecrdsa_tv_template[] = { { @@ -1973,6 +2109,195 @@ static const struct sig_testvec ecrdsa_tv_template[] = { .m_size = 64, .public_key_vec = true, }, + /* + * Constructed EC-RDSA exceptional-point vectors. + * With Q = dG, choose k = z1 + d*z2 (mod n), r = x(kG) mod n, + * e = -r/z2 (mod n), and s = r*d + k*e (mod n). + * The input digest is e, encoded little-endian. + */ + /* cp256a: Q=G, z1 = 3, z2 = 1. */ + { + .key = + "\x04\x40\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x14\x1e\x9f\x9e\x9c\xc9\xac\x22\xb1\xe3\x23\xdf\x2d\x4f" + "\x29\x35\x76\x2b\x3f\x45\x5a\x50\xdf\x27\xda\x9c\x98\xe0\x71\xe4" + "\x91\x8d", + .key_len = 66, + .params = /* OID_gostCPSignA */ + "\x30\x13\x06\x07\x2a\x85\x03\x02\x02\x23\x01\x06\x08\x2a\x85\x03" + "\x07\x01\x01\x02\x02", + .param_len = 21, + .c = + "\x1a\xed\x44\xae\xd4\x4a\xed\x44\xae\xd4\x4a\xed\x44\xae\xd4\x49" + "\x32\x67\xe0\x26\x16\xfd\xb7\xaf\xa4\xd7\x3e\x61\xd4\xf9\x7b\x94" + "\xf7\x06\x3e\x70\x63\xe7\x06\x3e\x70\x63\xe7\x06\x3e\x70\x63\xe7" + "\x06\x3e\x70\x63\xe7\x06\x3e\x70\x63\xe7\x06\x3e\x70\x63\xe4\xb7", + .c_size = 64, + .m = + "\xdc\xd3\xfd\x46\xcb\x14\x9d\xe1\x8f\x92\x54\xb2\x0c\xa0\x22\x66" + "\x18\x9c\x8f\xc1\xf9\x18\x9c\x8f\xc1\xf9\x18\x9c\x8f\xc1\xf9\x08", + .m_size = 32, + .algo = OID_gost2012PKey256, + .public_key_vec = true, + }, + /* cp256a: Q=-G, z1 = 7, z2 = 6. */ + { + .key = + "\x04\x40\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x83\xdf\x60\x61\x63\x36\x53\xdd\x4e\x1c\xdc\x20\xd2\xb0" + "\xd6\xca\x89\xd4\xc0\xba\xa5\xaf\x20\xd8\x25\x63\x67\x1f\x8e\x1b" + "\x6e\x72", + .key_len = 66, + .params = /* OID_gostCPSignA */ + "\x30\x13\x06\x07\x2a\x85\x03\x02\x02\x23\x01\x06\x08\x2a\x85\x03" + "\x07\x01\x01\x02\x02", + .param_len = 21, + .c = + "\x2a\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\x92\x10\x2d\x68\x19\x8f\x22\xd5\x60\xeb\x59\xd6\xf3\xe5\x9e\xc2" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01", + .c_size = 64, + .m = + "\xc3\x9e\xe5\xf3\xd6\x59\xeb\x60\xd5\x22\x8f\x19\x68\x2d\x10\x92" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\x2a", + .m_size = 32, + .algo = OID_gost2012PKey256, + .public_key_vec = true, + }, + /* cp256a: Q=-2G, z1 = 5, z2 = 2. */ + { + .key = + "\x04\x40\x95\xfd\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\x14\x1e\x9f\x9e\x9c\xc9\xac\x22\xb1\xe3\x23\xdf\x2d\x4f" + "\x29\x35\x76\x2b\x3f\x45\x5a\x50\xdf\x27\xda\x9c\x98\xe0\x71\xe4" + "\x91\x8d", + .key_len = 66, + .params = /* OID_gostCPSignA */ + "\x30\x13\x06\x07\x2a\x85\x03\x02\x02\x23\x01\x06\x08\x2a\x85\x03" + "\x07\x01\x01\x02\x02", + .param_len = 21, + .c = + "\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + "\xb6\x30\x88\x38\x4c\xad\x68\x80\x22\xc2\x0d\x84\xdb\xb0\xdc\x47" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01", + .c_size = 64, + .m = + "\x49\xdc\xb0\xdb\x84\x0d\xc2\x22\x80\x68\xad\x4c\x38\x88\x30\xb6" + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7f", + .m_size = 32, + .algo = OID_gost2012PKey256, + .public_key_vec = true, + }, + /* tc512a: Q=G, z1 = 3, z2 = 1. */ + { + .key = + "\x04\x81\x80\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\xa4\xf2\x15\x52\xcb\x89\xa5\x89\xb8\xf5\x35\xc2\x5f" + "\xfe\x28\x80\xe9\x41\x3a\x0e\xa5\xe6\x75\x3d\xe9\x36\xd0\x4f\xbe" + "\x26\x16\xdf\x21\xa9\xef\xcb\xfd\x64\x80\x77\xc1\xab\xf1\xac\x93" + "\x1c\x5e\xce\xe6\x50\x54\xe2\x16\x88\x1b\xa6\xe3\x6a\x83\x7a\xe8" + "\xcf\x03\x75", + .key_len = 131, + .params = /* OID_gostTC26Sign512A */ + "\x30\x0b\x06\x09\x2a\x85\x03\x07\x01\x02\x01\x02\x01", + .param_len = 13, + .c = + "\xd8\xc0\xd7\xe3\xfb\xa6\xca\xff\x6a\xd1\xb4\xb4\x82\x1d\x15\x6f" + "\xa7\xc7\xbd\x63\x95\xb8\x29\x0d\xd4\xfa\xb1\x1c\x36\xbd\x32\x8d" + "\x1a\xba\xf1\x2e\xbc\x7b\xf2\x02\x96\xf8\xef\x2a\x5e\x72\x64\x86" + "\x67\x62\xfb\x62\x8e\x83\x53\x63\xb7\xe6\x78\x3c\x42\xd7\x0d\x1d" + "\xb7\xbf\xb8\x09\x56\xc8\x67\x00\x31\xba\x19\x19\x29\xf6\x4e\x30" + "\x1d\x68\x16\x34\x23\x6d\x47\xa6\x0e\x57\x1a\x4b\xed\xc0\xef\x25" + "\x74\x52\xef\x78\xb5\xb9\x8d\xbb\x3d\x9f\x31\x29\xd9\x34\x94\x33" + "\xce\x2a\x3a\x35\xcb\x51\x9c\x91\xe2\xd6\x33\xd7\xb3\x73\xae\x16", + .c_size = 128, + .m = + "\x5f\x04\x9d\x6b\x69\x7d\xf7\xe7\xcb\x1b\x81\x2f\x76\xfe\x20\xcd" + "\x2c\xcc\xd0\x74\x63\xfa\x52\x32\x56\xfb\xd3\x3e\xba\xa5\x93\xb3" + "\xd9\x10\x3f\x12\xb4\xe5\xa8\xf1\x59\xb8\x92\xdc\xcb\xe9\x97\xe2" + "\xcf\xb1\x09\xd6\xe6\xe6\x45\xce\xff\x98\x37\xa9\xf6\x47\x40\x48", + .m_size = 64, + .algo = OID_gost2012PKey512, + .public_key_vec = true, + }, + /* tc512a: Q=-G, z1 = 7, z2 = 6. */ + { + .key = + "\x04\x81\x80\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x23\x0b\xea\xad\x34\x76\x5a\x76\x47\x0a\xca\x3d\xa0" + "\x01\xd7\x7f\x16\xbe\xc5\xf1\x5a\x19\x8a\xc2\x16\xc9\x2f\xb0\x41" + "\xd9\xe9\x20\xde\x56\x10\x34\x02\x9b\x7f\x88\x3e\x54\x0e\x53\x6c" + "\xe3\xa1\x31\x19\xaf\xab\x1d\xe9\x77\xe4\x59\x1c\x95\x7c\x85\x17" + "\x30\xfc\x8a", + .key_len = 131, + .params = /* OID_gostTC26Sign512A */ + "\x30\x0b\x06\x09\x2a\x85\x03\x07\x01\x02\x01\x02\x01", + .param_len = 13, + .c = + "\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + "\x93\xf3\x4a\x99\x7a\x46\xc4\x88\xb7\xf9\x15\xc6\xa7\x02\xb0\x30" + "\x4d\xa5\x9c\x55\xfd\x69\x5c\x2e\xe5\x66\xd8\xa0\x8f\x88\x59\x37" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03", + .c_size = 128, + .m = + "\x3a\x59\x88\x8f\xa0\xd8\x66\xe5\x2e\x5c\x69\xfd\x55\x9c\xa5\x4d" + "\x30\xb0\x02\xa7\xc6\x15\xf9\xb7\x88\xc4\x46\x7a\x99\x4a\xf3\x93" + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7f", + .m_size = 64, + .algo = OID_gost2012PKey512, + .public_key_vec = true, + }, + /* tc512a: Q=-2G, z1 = 5, z2 = 2. */ + { + .key = + "\x04\x81\x80\x7c\x13\xea\xd2\xd9\xaf\x82\xb9\x1f\xb2\xfd\xe1\x8d" + "\xf4\x5b\x37\xe4\xf2\x04\x6a\x2a\x1d\x15\x16\x95\x2a\x5d\x40\xcd" + "\xbb\x34\x44\x2f\x2b\x13\x0a\x47\xb0\xf6\xe5\xa5\x58\x3a\xf4\x54" + "\x09\xb0\x1d\xf5\x5c\xf1\xbf\x9d\x86\xa5\x97\xab\x96\x29\x62\xfc" + "\xdc\x89\x3b\x76\x3d\x50\x6e\x8a\xcf\x02\x4c\x74\x0e\x6e\xe0\x1f" + "\x28\xab\x27\x9b\x20\x02\xc8\xc4\x12\xcb\x8a\xe3\xa4\x27\xce\x39" + "\x62\xdf\x35\x6d\xc1\x65\x7f\x7b\x48\x90\x11\x8f\x19\x7c\x1e\x67" + "\x91\x97\xeb\x90\x85\x25\xfc\x86\xb3\x88\x6e\x5c\x57\x1f\x1d\x1d" + "\x3b\xec\x37", + .key_len = 131, + .params = /* OID_gostTC26Sign512A */ + "\x30\x0b\x06\x09\x2a\x85\x03\x07\x01\x02\x01\x02\x01", + .param_len = 13, + .c = + "\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + "\x93\xf3\x4a\x99\x7a\x46\xc4\x88\xb7\xf9\x15\xc6\xa7\x02\xb0\x30" + "\x4d\xa5\x9c\x55\xfd\x69\x5c\x2e\xe5\x66\xd8\xa0\x8f\x88\x59\x33" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03", + .c_size = 128, + .m = + "\x39\x59\x88\x8f\xa0\xd8\x66\xe5\x2e\x5c\x69\xfd\x55\x9c\xa5\x4d" + "\x30\xb0\x02\xa7\xc6\x15\xf9\xb7\x88\xc4\x46\x7a\x99\x4a\xf3\x93" + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7f", + .m_size = 64, + .algo = OID_gost2012PKey512, + .public_key_vec = true, + }, }; /* diff --git a/crypto/zstd.c b/crypto/zstd.c index 556f5d2bdd5f..76bdaca32733 100644 --- a/crypto/zstd.c +++ b/crypto/zstd.c @@ -96,6 +96,7 @@ static int zstd_compress_one(struct acomp_req *req, struct zstd_ctx *ctx, static int zstd_compress(struct acomp_req *req) { + bool stream_initialized = false; struct crypto_acomp_stream *s; unsigned int pos, scur, dcur; unsigned int total_out = 0; @@ -115,12 +116,6 @@ static int zstd_compress(struct acomp_req *req) if (ret) goto out; - ctx->cctx = zstd_init_cstream(&ctx->params, 0, ctx->wksp, ctx->wksp_size); - if (!ctx->cctx) { - ret = -EINVAL; - goto out; - } - do { dcur = acomp_walk_next_dst(&walk); if (!dcur) { @@ -142,6 +137,19 @@ static int zstd_compress(struct acomp_req *req) goto out; } + if (!stream_initialized) { + ctx->cctx = zstd_init_cstream(&ctx->params, 0, + ctx->wksp, ctx->wksp_size); + if (!ctx->cctx) { + /* Release in the reverse of the map order. */ + acomp_walk_done_src(&walk, 0); + acomp_walk_done_dst(&walk, 0); + ret = -EINVAL; + goto out; + } + stream_initialized = true; + } + if (scur) { inbuf.pos = 0; inbuf.src = walk.src.virt.addr; @@ -207,6 +215,7 @@ static int zstd_decompress_one(struct acomp_req *req, struct zstd_ctx *ctx, static int zstd_decompress(struct acomp_req *req) { + bool stream_initialized = false; struct crypto_acomp_stream *s; unsigned int total_out = 0; unsigned int scur, dcur; @@ -224,12 +233,6 @@ static int zstd_decompress(struct acomp_req *req) if (ret) goto out; - ctx->dctx = zstd_init_dstream(ZSTD_MAX_SIZE, ctx->wksp, ctx->wksp_size); - if (!ctx->dctx) { - ret = -EINVAL; - goto out; - } - do { scur = acomp_walk_next_src(&walk); if (scur) { @@ -255,6 +258,19 @@ static int zstd_decompress(struct acomp_req *req) goto out; } + if (!stream_initialized) { + ctx->dctx = zstd_init_dstream(ZSTD_MAX_SIZE, ctx->wksp, + ctx->wksp_size); + if (!ctx->dctx) { + /* Release in the reverse of the map order. */ + acomp_walk_done_dst(&walk, 0); + acomp_walk_done_src(&walk, 0); + ret = -EINVAL; + goto out; + } + stream_initialized = true; + } + outbuf.pos = 0; outbuf.dst = (u8 *)walk.dst.virt.addr; outbuf.size = dcur; diff --git a/drivers/char/hw_random/amd-rng.c b/drivers/char/hw_random/amd-rng.c index dff80daae587..ef177c99515d 100644 --- a/drivers/char/hw_random/amd-rng.c +++ b/drivers/char/hw_random/amd-rng.c @@ -80,7 +80,7 @@ static int amd_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait) if (timeout-- == 0) return read; } else { - return 0; + return read; } } else { *data = ioread32(priv->iobase + RNGDATA); @@ -129,19 +129,15 @@ static int __init amd_rng_mod_init(void) { int err; struct pci_dev *pdev = NULL; - const struct pci_device_id *ent; u32 pmbase; struct amd768_priv *priv; - for_each_pci_dev(pdev) { - ent = pci_match_id(pci_tbl, pdev); - if (ent) - goto found; - } - /* Device not found. */ - return -ENODEV; + for_each_pci_dev(pdev) + if (pci_match_id(pci_tbl, pdev)) + break; + if (!pdev) + return -ENODEV; -found: err = pci_read_config_dword(pdev, 0x58, &pmbase); if (err) { err = pcibios_err_to_errno(err); @@ -162,16 +158,16 @@ found: if (!request_region(pmbase + PMBASE_OFFSET, PMBASE_SIZE, DRV_NAME)) { dev_err(&pdev->dev, DRV_NAME " region 0x%x already in use!\n", - pmbase + 0xF0); + pmbase + PMBASE_OFFSET); err = -EBUSY; goto out; } priv->iobase = ioport_map(pmbase + PMBASE_OFFSET, PMBASE_SIZE); if (!priv->iobase) { - pr_err(DRV_NAME "Cannot map ioport\n"); + pr_err(DRV_NAME " cannot map ioport\n"); err = -EINVAL; - goto err_iomap; + goto err; } amd_rng.priv = (unsigned long)priv; @@ -182,13 +178,12 @@ found: err = hwrng_register(&amd_rng); if (err) { pr_err(DRV_NAME " registering failed (%d)\n", err); - goto err_hwrng; + ioport_unmap(priv->iobase); + goto err; } return 0; -err_hwrng: - ioport_unmap(priv->iobase); -err_iomap: +err: release_region(pmbase + PMBASE_OFFSET, PMBASE_SIZE); out: kfree(priv); diff --git a/drivers/char/hw_random/atmel-rng.c b/drivers/char/hw_random/atmel-rng.c index 06e79d516743..fe444196e6b3 100644 --- a/drivers/char/hw_random/atmel-rng.c +++ b/drivers/char/hw_random/atmel-rng.c @@ -17,6 +17,7 @@ #include <linux/of.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> +#include <linux/units.h> #define TRNG_CR 0x00 #define TRNG_MR 0x04 @@ -85,20 +86,14 @@ out: static int atmel_trng_init(struct atmel_trng *trng) { - unsigned long rate; int ret; ret = clk_prepare_enable(trng->clk); if (ret) return ret; - if (trng->has_half_rate) { - rate = clk_get_rate(trng->clk); - - /* if peripheral clk is above 100MHz, set HALFR */ - if (rate > 100000000) - writel(TRNG_HALFR, trng->base + TRNG_MR); - } + if (trng->has_half_rate && clk_get_rate(trng->clk) > 100 * HZ_PER_MHZ) + writel(TRNG_HALFR, trng->base + TRNG_MR); writel(TRNG_KEY | 1, trng->base + TRNG_CR); diff --git a/drivers/char/hw_random/ba431-rng.c b/drivers/char/hw_random/ba431-rng.c index b0a39032c610..810c8cd5629a 100644 --- a/drivers/char/hw_random/ba431-rng.c +++ b/drivers/char/hw_random/ba431-rng.c @@ -147,7 +147,7 @@ static int ba431_trng_read(struct hwrng *rng, void *buf, size_t max, bool wait) } } - n *= sizeof(data); + n *= sizeof(*data); return (n || !wait) ? n : -EIO; } diff --git a/drivers/char/hw_random/cctrng.c b/drivers/char/hw_random/cctrng.c index a6925211c3b5..03401ee59a8e 100644 --- a/drivers/char/hw_random/cctrng.c +++ b/drivers/char/hw_random/cctrng.c @@ -86,17 +86,12 @@ static inline u32 cc_ioread(struct cctrng_drvdata *drvdata, u32 reg) static int cc_trng_pm_get(struct device *dev) { - int rc = 0; - - rc = pm_runtime_get_sync(dev); - - /* pm_runtime_get_sync() can return 1 as a valid return code */ - return (rc == 1 ? 0 : rc); + return pm_runtime_resume_and_get(dev); } static void cc_trng_pm_put_suspend(struct device *dev) { - int rc = 0; + int rc; rc = pm_runtime_put_autosuspend(dev); if (rc) @@ -213,7 +208,7 @@ static int cctrng_read(struct hwrng *rng, void *data, size_t max, bool wait) struct cctrng_drvdata *drvdata = (struct cctrng_drvdata *)rng->priv; struct device *dev = &(drvdata->pdev->dev); u32 *buf = (u32 *)drvdata->circ.buf; - size_t copied = 0; + size_t copied; size_t cnt_w; size_t size; size_t left; @@ -273,7 +268,7 @@ static int cctrng_read(struct hwrng *rng, void *data, size_t max, bool wait) static void cc_trng_hw_trigger(struct cctrng_drvdata *drvdata) { - u32 tmp_smpl_cnt = 0; + u32 tmp_smpl_cnt; struct device *dev = &(drvdata->pdev->dev); dev_dbg(dev, "cctrng hw trigger.\n"); @@ -314,8 +309,8 @@ static void cc_trng_hw_trigger(struct cctrng_drvdata *drvdata) static void cc_trng_compwork_handler(struct work_struct *w) { - u32 isr = 0; - u32 ehr_valid = 0; + u32 isr; + u32 ehr_valid; struct cctrng_drvdata *drvdata = container_of(w, struct cctrng_drvdata, compwork); struct device *dev = &(drvdata->pdev->dev); @@ -458,7 +453,7 @@ static int cctrng_probe(struct platform_device *pdev) { struct cctrng_drvdata *drvdata; struct device *dev = &pdev->dev; - int rc = 0; + int rc; u32 val; int irq; @@ -539,7 +534,8 @@ static int cctrng_probe(struct platform_device *pdev) rc = devm_hwrng_register(dev, &drvdata->rng); if (rc) { dev_err(dev, "Could not register hwrng device.\n"); - goto post_pm_err; + cc_trng_pm_fini(drvdata); + return rc; } /* trigger HW to start generate data */ @@ -552,11 +548,6 @@ static int cctrng_probe(struct platform_device *pdev) dev_info(dev, "ARM cctrng device initialized\n"); return 0; - -post_pm_err: - cc_trng_pm_fini(drvdata); - - return rc; } static void cctrng_remove(struct platform_device *pdev) diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c index 57eeefe90da9..1f9e31cdc7f0 100644 --- a/drivers/char/hw_random/core.c +++ b/drivers/char/hw_random/core.c @@ -376,6 +376,7 @@ static ssize_t rng_current_store(struct device *dev, cur_rng_set_by_user = 1; drop_current_rng(); } else { + err = -ENODEV; list_for_each_entry(rng, &rng_list, list) { if (sysfs_streq(rng->name, buf)) { err = set_current_rng(rng); diff --git a/drivers/char/hw_random/imx-rngc.c b/drivers/char/hw_random/imx-rngc.c index 7693328f1056..a09532384b9f 100644 --- a/drivers/char/hw_random/imx-rngc.c +++ b/drivers/char/hw_random/imx-rngc.c @@ -258,7 +258,7 @@ static int __init imx_rngc_probe(struct platform_device *pdev) if (IS_ERR(rngc->base)) return PTR_ERR(rngc->base); - rngc->clk = devm_clk_get(&pdev->dev, NULL); + rngc->clk = devm_clk_get_optional(&pdev->dev, NULL); if (IS_ERR(rngc->clk)) return dev_err_probe(&pdev->dev, PTR_ERR(rngc->clk), "Cannot get rng_clk\n"); @@ -266,7 +266,9 @@ static int __init imx_rngc_probe(struct platform_device *pdev) if (irq < 0) return irq; - clk_prepare_enable(rngc->clk); + ret = clk_prepare_enable(rngc->clk); + if (ret) + return dev_err_probe(&pdev->dev, ret, "Cannot enable rng_clk\n"); ver_id = readl(rngc->base + RNGC_VER_ID); rng_type = FIELD_GET(RNG_TYPE, ver_id); @@ -338,9 +340,7 @@ static int imx_rngc_resume(struct device *dev) { struct imx_rngc *rngc = dev_get_drvdata(dev); - clk_prepare_enable(rngc->clk); - - return 0; + return clk_prepare_enable(rngc->clk); } static const struct dev_pm_ops imx_rngc_pm_ops = { diff --git a/drivers/char/hw_random/intel-rng.c b/drivers/char/hw_random/intel-rng.c index d24e747203c1..b6a50e3e7a6a 100644 --- a/drivers/char/hw_random/intel-rng.c +++ b/drivers/char/hw_random/intel-rng.c @@ -305,11 +305,11 @@ static int __init intel_init_hw_struct(struct intel_rng_hw *intel_rng_hw, if ((intel_rng_hw->bios_cntl_val & (BIOS_CNTL_LOCK_ENABLE_MASK|BIOS_CNTL_WRITE_ENABLE_MASK)) == BIOS_CNTL_LOCK_ENABLE_MASK) { - static __initdata /*const*/ char warning[] = -PFX "Firmware space is locked read-only. If you can't or\n" -PFX "don't want to disable this in firmware setup, and if\n" -PFX "you are certain that your system has a functional\n" -PFX "RNG, try using the 'no_fwh_detect' option.\n"; + static const char warning[] __initconst = + PFX "Firmware space is locked read-only. If you can't or\n" + PFX "don't want to disable this in firmware setup, and if\n" + PFX "you are certain that your system has a functional\n" + PFX "RNG, try using the 'no_fwh_detect' option.\n"; if (no_fwh_detect) return -ENODEV; @@ -318,8 +318,8 @@ PFX "RNG, try using the 'no_fwh_detect' option.\n"; } intel_rng_hw->mem = ioremap(INTEL_FWH_ADDR, INTEL_FWH_ADDR_LEN); - if (intel_rng_hw->mem == NULL) - return -EBUSY; + if (!intel_rng_hw->mem) + return -ENOMEM; return 0; } @@ -327,7 +327,7 @@ PFX "RNG, try using the 'no_fwh_detect' option.\n"; static int __init intel_rng_mod_init(void) { - int err = -ENODEV; + int err; int i; struct pci_dev *dev = NULL; void __iomem *mem; @@ -339,7 +339,7 @@ static int __init intel_rng_mod_init(void) NULL); if (!dev) - goto out; /* Device not found. */ + return -ENODEV; if (no_fwh_detect < 0) { pci_dev_put(dev); @@ -349,7 +349,7 @@ static int __init intel_rng_mod_init(void) intel_rng_hw = kmalloc_obj(*intel_rng_hw); if (!intel_rng_hw) { pci_dev_put(dev); - goto out; + return -ENOMEM; } err = intel_init_hw_struct(intel_rng_hw, dev); @@ -358,7 +358,7 @@ static int __init intel_rng_mod_init(void) kfree(intel_rng_hw); if (err == -ENODEV) goto fwh_done; - goto out; + return err; } /* @@ -374,21 +374,19 @@ static int __init intel_rng_mod_init(void) iounmap(intel_rng_hw->mem); kfree(intel_rng_hw); if (err) - goto out; + return err; fwh_done: - err = -ENOMEM; mem = ioremap(INTEL_RNG_ADDR, INTEL_RNG_ADDR_LEN); if (!mem) - goto out; + return -ENOMEM; intel_rng.priv = (unsigned long)mem; /* Check for Random Number Generator */ - err = -ENODEV; hw_status = hwstatus_get(mem); if ((hw_status & INTEL_RNG_PRESENT) == 0) { iounmap(mem); - goto out; + return -ENODEV; } pr_info("Intel 82802 RNG detected\n"); @@ -397,10 +395,10 @@ fwh_done: pr_err(PFX "RNG registering failed (%d)\n", err); iounmap(mem); + return err; } -out: - return err; + return 0; } static void __exit intel_rng_mod_exit(void) diff --git a/drivers/char/hw_random/jh7110-trng.c b/drivers/char/hw_random/jh7110-trng.c index aee12caab578..61eb4db7ac01 100644 --- a/drivers/char/hw_random/jh7110-trng.c +++ b/drivers/char/hw_random/jh7110-trng.c @@ -320,9 +320,17 @@ static int starfive_trng_probe(struct platform_device *pdev) return dev_err_probe(&pdev->dev, PTR_ERR(trng->rst), "Error getting hardware reset line\n"); - clk_prepare_enable(trng->hclk); - clk_prepare_enable(trng->ahb); - reset_control_deassert(trng->rst); + ret = clk_prepare_enable(trng->hclk); + if (ret) + return ret; + + ret = clk_prepare_enable(trng->ahb); + if (ret) + goto disable_hclk; + + ret = reset_control_deassert(trng->rst); + if (ret) + goto disable_ahb; trng->rng.name = dev_driver_string(&pdev->dev); trng->rng.init = starfive_trng_init; @@ -342,13 +350,18 @@ static int starfive_trng_probe(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); reset_control_assert(trng->rst); - clk_disable_unprepare(trng->ahb); - clk_disable_unprepare(trng->hclk); - - return dev_err_probe(&pdev->dev, ret, "Failed to register hwrng\n"); + ret = dev_err_probe(&pdev->dev, ret, "Failed to register hwrng\n"); + goto disable_ahb; } return 0; + +disable_ahb: + clk_disable_unprepare(trng->ahb); +disable_hclk: + clk_disable_unprepare(trng->hclk); + + return ret; } static int __maybe_unused starfive_trng_suspend(struct device *dev) @@ -364,11 +377,17 @@ static int __maybe_unused starfive_trng_suspend(struct device *dev) static int __maybe_unused starfive_trng_resume(struct device *dev) { struct starfive_trng *trng = dev_get_drvdata(dev); + int ret; + + ret = clk_prepare_enable(trng->hclk); + if (ret) + return ret; - clk_prepare_enable(trng->hclk); - clk_prepare_enable(trng->ahb); + ret = clk_prepare_enable(trng->ahb); + if (ret) + clk_disable_unprepare(trng->hclk); - return 0; + return ret; } static const struct dev_pm_ops starfive_trng_pm_ops = { diff --git a/drivers/char/hw_random/omap-rng.c b/drivers/char/hw_random/omap-rng.c index 9f0545c67774..22cde35ebe5d 100644 --- a/drivers/char/hw_random/omap-rng.c +++ b/drivers/char/hw_random/omap-rng.c @@ -530,7 +530,7 @@ static void omap_rng_remove(struct platform_device *pdev) clk_disable_unprepare(priv->clk_reg); } -static int __maybe_unused omap_rng_suspend(struct device *dev) +static int omap_rng_suspend(struct device *dev) { struct omap_rng_dev *priv = dev_get_drvdata(dev); @@ -540,7 +540,7 @@ static int __maybe_unused omap_rng_suspend(struct device *dev) return 0; } -static int __maybe_unused omap_rng_resume(struct device *dev) +static int omap_rng_resume(struct device *dev) { struct omap_rng_dev *priv = dev_get_drvdata(dev); int ret; @@ -556,12 +556,12 @@ static int __maybe_unused omap_rng_resume(struct device *dev) return 0; } -static SIMPLE_DEV_PM_OPS(omap_rng_pm, omap_rng_suspend, omap_rng_resume); +static DEFINE_SIMPLE_DEV_PM_OPS(omap_rng_pm, omap_rng_suspend, omap_rng_resume); static struct platform_driver omap_rng_driver = { .driver = { .name = "omap_rng", - .pm = &omap_rng_pm, + .pm = pm_sleep_ptr(&omap_rng_pm), .of_match_table = of_match_ptr(omap_rng_of_match), }, .probe = omap_rng_probe, diff --git a/drivers/char/hw_random/omap3-rom-rng.c b/drivers/char/hw_random/omap3-rom-rng.c index aa71f61c3dc9..0797add0d782 100644 --- a/drivers/char/hw_random/omap3-rom-rng.c +++ b/drivers/char/hw_random/omap3-rom-rng.c @@ -42,12 +42,9 @@ static int omap3_rom_rng_read(struct hwrng *rng, void *data, size_t max, bool w) ddata = (struct omap_rom_rng *)rng->priv; - r = pm_runtime_get_sync(ddata->dev); - if (r < 0) { - pm_runtime_put_noidle(ddata->dev); - + r = pm_runtime_resume_and_get(ddata->dev); + if (r < 0) return r; - } ptr = virt_to_phys(data); r = ddata->rom_rng_call(ptr, 4, RNG_GEN_HW); diff --git a/drivers/char/hw_random/stm32-rng.c b/drivers/char/hw_random/stm32-rng.c index f5bfe54c01dc..739263eb56ba 100644 --- a/drivers/char/hw_random/stm32-rng.c +++ b/drivers/char/hw_random/stm32-rng.c @@ -156,7 +156,7 @@ end: */ static int stm32_rng_conceal_seed_error_sw_reset(struct stm32_rng_private *priv) { - unsigned int i = 0; + unsigned int i; u32 sr = readl_relaxed(priv->base + RNG_SR); writel_relaxed(sr & ~RNG_SR_SEIS, priv->base + RNG_SR); @@ -187,7 +187,7 @@ static int stm32_rng_read(struct hwrng *rng, void *data, size_t max, bool wait) { struct stm32_rng_private *priv = container_of(rng, struct stm32_rng_private, rng); unsigned int i = 0; - int retval = 0, err = 0; + int retval, err; u32 sr; retval = pm_runtime_resume_and_get(priv->dev); @@ -264,7 +264,7 @@ static uint stm32_rng_clock_freq_restrain(struct hwrng *rng) { struct stm32_rng_private *priv = container_of(rng, struct stm32_rng_private, rng); - unsigned long clock_rate = 0; + unsigned long clock_rate; uint clock_div = 0; clock_rate = clk_get_rate(priv->clk_bulk[0].clk); @@ -277,7 +277,7 @@ static uint stm32_rng_clock_freq_restrain(struct hwrng *rng) while ((clock_rate >> clock_div) > priv->data->max_clock_rate) clock_div++; - pr_debug("RNG clk rate : %lu\n", clk_get_rate(priv->clk_bulk[0].clk) >> clock_div); + pr_debug("RNG clk rate: %lu\n", clock_rate >> clock_div); return clock_div; } @@ -528,14 +528,13 @@ static int stm32_rng_probe(struct platform_device *ofdev) struct device *dev = &ofdev->dev; struct device_node *np = ofdev->dev.of_node; struct stm32_rng_private *priv; - struct resource *res; int ret; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; - priv->base = devm_platform_get_and_ioremap_resource(ofdev, 0, &res); + priv->base = devm_platform_ioremap_resource(ofdev, 0); if (IS_ERR(priv->base)) return PTR_ERR(priv->base); @@ -569,18 +568,11 @@ static int stm32_rng_probe(struct platform_device *ofdev) return dev_err_probe(dev, -EINVAL, "Failed to get clocks: %d\n", ret); if (priv->data->nb_clock == 2) { - const char *id = priv->clk_bulk[1].id; - struct clk *clk = priv->clk_bulk[1].clk; - if (!priv->clk_bulk[0].id || !priv->clk_bulk[1].id) return dev_err_probe(dev, -EINVAL, "Missing clock name\n"); - if (strcmp(priv->clk_bulk[0].id, "core")) { - priv->clk_bulk[1].id = priv->clk_bulk[0].id; - priv->clk_bulk[1].clk = priv->clk_bulk[0].clk; - priv->clk_bulk[0].id = id; - priv->clk_bulk[0].clk = clk; - } + if (strcmp(priv->clk_bulk[0].id, "core")) + swap(priv->clk_bulk[0], priv->clk_bulk[1]); } pm_runtime_set_autosuspend_delay(dev, 100); diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c index 5e83ffa105e4..f9982217247d 100644 --- a/drivers/char/hw_random/virtio-rng.c +++ b/drivers/char/hw_random/virtio-rng.c @@ -81,13 +81,13 @@ static unsigned int copy_data(struct virtrng_info *vi, void *buf, * steered into adjacent slab memory, including under * speculation. */ - avail = min_t(unsigned int, vi->data_avail, sizeof(vi->data)); + avail = min(vi->data_avail, sizeof(vi->data)); if (vi->data_idx >= avail) { vi->data_avail = 0; request_entropy(vi); return 0; } - size = min_t(unsigned int, size, avail - vi->data_idx); + size = min(size, avail - vi->data_idx); idx = array_index_nospec(vi->data_idx, sizeof(vi->data)); memcpy(buf, vi->data + idx, size); vi->data_idx += size; @@ -162,7 +162,7 @@ static int probe_common(struct virtio_device *vdev) err = index; goto err_ida; } - sprintf(vi->name, "virtio_rng.%d", index); + snprintf(vi->name, sizeof(vi->name), "virtio_rng.%d", vi->index); init_completion(&vi->have_data); vi->hwrng = (struct hwrng) { diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c index 36a1ebca2e70..56ba4ff6d5ff 100644 --- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c +++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c @@ -120,12 +120,11 @@ int sun8i_ss_hash_init_tfm(struct crypto_ahash *tfm) memcpy(algt->fbname, crypto_ahash_driver_name(op->fallback_tfm), CRYPTO_MAX_ALG_NAME); - err = pm_runtime_get_sync(op->ss->dev); + err = pm_runtime_resume_and_get(op->ss->dev); if (err < 0) goto error_pm; return 0; error_pm: - pm_runtime_put_noidle(op->ss->dev); crypto_free_ahash(op->fallback_tfm); return err; } diff --git a/drivers/crypto/amcc/crypto4xx_core.c b/drivers/crypto/amcc/crypto4xx_core.c index fd010bfb7020..acf18b71e54d 100644 --- a/drivers/crypto/amcc/crypto4xx_core.c +++ b/drivers/crypto/amcc/crypto4xx_core.c @@ -1046,8 +1046,7 @@ static void crypto4xx_bh_tasklet_cb(unsigned long data) static inline irqreturn_t crypto4xx_interrupt_handler(int irq, void *data, u32 clr_val) { - struct device *dev = data; - struct crypto4xx_core_device *core_dev = dev_get_drvdata(dev); + struct crypto4xx_core_device *core_dev = data; writel(clr_val, core_dev->dev->ce_base + CRYPTO4XX_INT_CLR); tasklet_schedule(&core_dev->tasklet); @@ -1206,9 +1205,19 @@ static int crypto4xx_probe(struct platform_device *ofdev) struct device *dev = &ofdev->dev; struct crypto4xx_core_device *core_dev; struct device_node *np; + void __iomem *ce_base; + int irq; u32 pvr; bool is_revb = true; + irq = platform_get_irq(ofdev, 0); + if (irq < 0) + return irq; + + ce_base = devm_platform_ioremap_resource(ofdev, 0); + if (IS_ERR(ce_base)) + return PTR_ERR(ce_base); + np = of_find_compatible_node(NULL, NULL, "amcc,ppc460ex-crypto"); if (np) { mtdcri(SDR0, PPC460EX_SDR0_SRST, @@ -1251,9 +1260,7 @@ static int crypto4xx_probe(struct platform_device *ofdev) if (!core_dev->dev) return -ENOMEM; - core_dev->dev->ce_base = devm_platform_ioremap_resource(ofdev, 0); - if (IS_ERR(core_dev->dev->ce_base)) - return PTR_ERR(core_dev->dev->ce_base); + core_dev->dev->ce_base = ce_base; /* * Older version of 460EX/GT have a hardware bug. @@ -1291,15 +1298,11 @@ static int crypto4xx_probe(struct platform_device *ofdev) (unsigned long) dev); /* Register for Crypto isr, Crypto Engine IRQ */ - core_dev->irq = platform_get_irq(ofdev, 0); - if (core_dev->irq < 0) { - rc = core_dev->irq; - goto err_tasklet; - } + core_dev->irq = irq; rc = request_irq(core_dev->irq, is_revb ? crypto4xx_ce_interrupt_handler_revb : crypto4xx_ce_interrupt_handler, - 0, KBUILD_MODNAME, dev); + 0, KBUILD_MODNAME, core_dev); if (rc) goto err_tasklet; @@ -1312,11 +1315,15 @@ static int crypto4xx_probe(struct platform_device *ofdev) if (rc) goto err_irq; - ppc4xx_trng_probe(core_dev); + rc = ppc4xx_trng_probe(core_dev); + if (rc) + goto err_crypto; return 0; +err_crypto: + crypto4xx_unregister_alg(core_dev->dev); err_irq: - free_irq(core_dev->irq, dev); + free_irq(core_dev->irq, core_dev); err_tasklet: tasklet_kill(&core_dev->tasklet); err_build_sdr: @@ -1337,7 +1344,7 @@ static void crypto4xx_remove(struct platform_device *ofdev) * Free IRQ before killing the tasklet to prevent the interrupt * handler from rescheduling the tasklet after it has been killed. */ - free_irq(core_dev->irq, dev); + free_irq(core_dev->irq, core_dev); tasklet_kill(&core_dev->tasklet); /* Un-register with Linux CryptoAPI */ crypto4xx_unregister_alg(core_dev->dev); diff --git a/drivers/crypto/amcc/crypto4xx_trng.c b/drivers/crypto/amcc/crypto4xx_trng.c index cfd66b779ce1..83e9353529fc 100644 --- a/drivers/crypto/amcc/crypto4xx_trng.c +++ b/drivers/crypto/amcc/crypto4xx_trng.c @@ -68,7 +68,7 @@ static const struct of_device_id ppc4xx_trng_match[] = { {}, }; -void ppc4xx_trng_probe(struct crypto4xx_core_device *core_dev) +int ppc4xx_trng_probe(struct crypto4xx_core_device *core_dev) { struct crypto4xx_device *dev = core_dev->dev; struct device_node *trng = NULL; @@ -79,17 +79,21 @@ void ppc4xx_trng_probe(struct crypto4xx_core_device *core_dev) trng = of_find_matching_node(NULL, ppc4xx_trng_match); if (!trng || !of_device_is_available(trng)) { of_node_put(trng); - return; + return 0; } dev->trng_base = of_iomap(trng, 0); of_node_put(trng); - if (!dev->trng_base) + if (!dev->trng_base) { + err = -EINVAL; goto err_out; + } rng = kzalloc_obj(*rng); - if (!rng) + if (!rng) { + err = -ENOMEM; goto err_out; + } rng->name = KBUILD_MODNAME; rng->data_present = ppc4xx_trng_data_present; @@ -105,13 +109,14 @@ void ppc4xx_trng_probe(struct crypto4xx_core_device *core_dev) err); goto err_out; } - return; + return 0; err_out: iounmap(dev->trng_base); kfree(rng); dev->trng_base = NULL; core_dev->trng = NULL; + return err; } void ppc4xx_trng_remove(struct crypto4xx_core_device *core_dev) diff --git a/drivers/crypto/amcc/crypto4xx_trng.h b/drivers/crypto/amcc/crypto4xx_trng.h index 7356716274cb..1030c3cfafd0 100644 --- a/drivers/crypto/amcc/crypto4xx_trng.h +++ b/drivers/crypto/amcc/crypto4xx_trng.h @@ -13,11 +13,11 @@ #define __CRYPTO4XX_TRNG_H__ #ifdef CONFIG_HW_RANDOM_PPC4XX -void ppc4xx_trng_probe(struct crypto4xx_core_device *core_dev); +int ppc4xx_trng_probe(struct crypto4xx_core_device *core_dev); void ppc4xx_trng_remove(struct crypto4xx_core_device *core_dev); #else -static inline void ppc4xx_trng_probe( - struct crypto4xx_core_device *dev __maybe_unused) { } +static inline int ppc4xx_trng_probe( + struct crypto4xx_core_device *dev __maybe_unused) { return 0; } static inline void ppc4xx_trng_remove( struct crypto4xx_core_device *dev __maybe_unused) { } #endif diff --git a/drivers/crypto/amlogic/amlogic-gxl-cipher.c b/drivers/crypto/amlogic/amlogic-gxl-cipher.c index 29048da6f50a..d78815b0547d 100644 --- a/drivers/crypto/amlogic/amlogic-gxl-cipher.c +++ b/drivers/crypto/amlogic/amlogic-gxl-cipher.c @@ -177,10 +177,13 @@ static int meson_cipher(struct skcipher_request *areq) if (areq->src == areq->dst) { nr_sgs = dma_map_sg(mc->dev, areq->src, sg_nents(areq->src), DMA_BIDIRECTIONAL); - if (!nr_sgs) { - dev_err(mc->dev, "Invalid SG count %d\n", nr_sgs); + if (!nr_sgs || nr_sgs > MAXDESC - 3) { + dev_err(mc->dev, "Invalid BIDIR SG count %d\n", nr_sgs); err = -EINVAL; - goto theend; + + if (nr_sgs) + dma_unmap_sg(mc->dev, areq->src, sg_nents(areq->src), DMA_BIDIRECTIONAL); + goto error_keyiv; } nr_sgd = nr_sgs; } else { @@ -189,14 +192,20 @@ static int meson_cipher(struct skcipher_request *areq) if (!nr_sgs || nr_sgs > MAXDESC - 3) { dev_err(mc->dev, "Invalid SG count %d\n", nr_sgs); err = -EINVAL; - goto theend; + + if (nr_sgs) + dma_unmap_sg(mc->dev, areq->src, sg_nents(areq->src), DMA_TO_DEVICE); + goto error_keyiv; } nr_sgd = dma_map_sg(mc->dev, areq->dst, sg_nents(areq->dst), DMA_FROM_DEVICE); if (!nr_sgd || nr_sgd > MAXDESC - 3) { dev_err(mc->dev, "Invalid SG count %d\n", nr_sgd); err = -EINVAL; - goto theend; + + if (nr_sgd) + dma_unmap_sg(mc->dev, areq->dst, sg_nents(areq->dst), DMA_FROM_DEVICE); + goto error_src; } } @@ -251,6 +260,12 @@ static int meson_cipher(struct skcipher_request *areq) ivsize, 0); } } + goto theend; + +error_src: + dma_unmap_sg(mc->dev, areq->src, sg_nents(areq->src), DMA_TO_DEVICE); +error_keyiv: + dma_unmap_single(mc->dev, phykeyiv, keyivlen, DMA_TO_DEVICE); theend: kfree_sensitive(bkeyiv); kfree_sensitive(backup_iv); diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c index 169c6eeb51e5..d5d84524c110 100644 --- a/drivers/crypto/amlogic/amlogic-gxl-core.c +++ b/drivers/crypto/amlogic/amlogic-gxl-core.c @@ -37,12 +37,13 @@ static irqreturn_t meson_irq_handler(int irq, void *data) complete(&mc->chanlist[flow].complete); return IRQ_HANDLED; } - dev_err(mc->dev, "%s %d Got irq for flow %d but ctrl is empty\n", __func__, irq, flow); + dev_err_ratelimited(mc->dev, "%s %d Got irq for flow %d but ctrl is empty\n", __func__, irq, flow); + return IRQ_NONE; } } - dev_err(mc->dev, "%s %d from unknown irq\n", __func__, irq); - return IRQ_HANDLED; + dev_err_ratelimited(mc->dev, "%s %d from unknown irq\n", __func__, irq); + return IRQ_NONE; } static struct meson_alg_template mc_algs[] = { @@ -243,34 +244,30 @@ static int meson_crypto_probe(struct platform_device *pdev) if (IS_ERR(mc->base)) return PTR_ERR(mc->base); - mc->busclk = devm_clk_get(&pdev->dev, "blkmv"); + mc->busclk = devm_clk_get_enabled(&pdev->dev, "blkmv"); if (IS_ERR(mc->busclk)) { err = PTR_ERR(mc->busclk); - dev_err(&pdev->dev, "Cannot get core clock err=%d\n", err); + dev_err(&pdev->dev, "Cannot get/enable core clock err=%d\n", err); return err; } + err = meson_allocate_chanlist(mc); + if (err) + return err; + for (i = 0; i < MAXFLOW; i++) { mc->irqs[i] = platform_get_irq(pdev, i); - if (mc->irqs[i] < 0) - return mc->irqs[i]; + if (mc->irqs[i] < 0) { + err = mc->irqs[i]; + goto error_chanlist; + } err = devm_request_irq(&pdev->dev, mc->irqs[i], meson_irq_handler, 0, "gxl-crypto", mc); if (err < 0) - return err; - } - - err = clk_prepare_enable(mc->busclk); - if (err != 0) { - dev_err(&pdev->dev, "Cannot prepare_enable busclk\n"); - return err; + goto error_chanlist; } - err = meson_allocate_chanlist(mc); - if (err) - goto error_flow; - err = meson_register_algs(mc); if (err) goto error_alg; @@ -289,9 +286,8 @@ static int meson_crypto_probe(struct platform_device *pdev) return 0; error_alg: meson_unregister_algs(mc); +error_chanlist: meson_free_chanlist(mc, MAXFLOW - 1); -error_flow: - clk_disable_unprepare(mc->busclk); return err; } @@ -306,8 +302,6 @@ static void meson_crypto_remove(struct platform_device *pdev) meson_unregister_algs(mc); meson_free_chanlist(mc, MAXFLOW - 1); - - clk_disable_unprepare(mc->busclk); } static const struct of_device_id meson_crypto_of_match_table[] = { diff --git a/drivers/crypto/aspeed/aspeed-hace-crypto.c b/drivers/crypto/aspeed/aspeed-hace-crypto.c index fa201dae1f81..e7d3f611df05 100644 --- a/drivers/crypto/aspeed/aspeed-hace-crypto.c +++ b/drivers/crypto/aspeed/aspeed-hace-crypto.c @@ -576,7 +576,6 @@ static int aspeed_aes_setkey(struct crypto_skcipher *cipher, const u8 *key, { struct aspeed_cipher_ctx *ctx = crypto_skcipher_ctx(cipher); struct aspeed_hace_dev *hace_dev = ctx->hace_dev; - struct crypto_aes_ctx gen_aes_key; CIPHER_DBG(hace_dev, "keylen: %d bits\n", (keylen * 8)); @@ -585,9 +584,9 @@ static int aspeed_aes_setkey(struct crypto_skcipher *cipher, const u8 *key, return -EINVAL; if (ctx->hace_dev->version == AST2500_VERSION) { + struct crypto_aes_ctx gen_aes_key __cleanup(aes_zeroize_ctx); aes_expandkey(&gen_aes_key, key, keylen); memcpy(ctx->key, gen_aes_key.key_enc, AES_MAX_KEYLENGTH); - } else { memcpy(ctx->key, key, keylen); } diff --git a/drivers/crypto/atmel-aes.c b/drivers/crypto/atmel-aes.c index 50d97cef75b8..84392411b98d 100644 --- a/drivers/crypto/atmel-aes.c +++ b/drivers/crypto/atmel-aes.c @@ -1267,7 +1267,7 @@ static int atmel_aes_gcm_ghash_init(struct atmel_aes_dev *dd) struct atmel_aes_gcm_ctx *ctx = atmel_aes_gcm_ctx_cast(dd->ctx); /* Set the data length. */ - atmel_aes_write(dd, AES_AADLENR, dd->total); + atmel_aes_write(dd, AES_AADLENR, dd->datalen); atmel_aes_write(dd, AES_CLENR, 0); /* If needed, overwrite the GCM Intermediate Hash Word Registers */ @@ -1826,6 +1826,8 @@ static int atmel_aes_authenc_transfer(struct atmel_aes_dev *dd, int err, dd->is_async = true; if (err) return atmel_aes_complete(dd, err); + if (!rctx->textlen) + return atmel_aes_authenc_digest(dd); /* Prepare src and dst scatter-lists to transfer cipher/plain texts. */ src = scatterwalk_ffwd(rctx->src, req->src, req->assoclen); diff --git a/drivers/crypto/atmel-ecc.c b/drivers/crypto/atmel-ecc.c index 075f38a67935..b538e818a26f 100644 --- a/drivers/crypto/atmel-ecc.c +++ b/drivers/crypto/atmel-ecc.c @@ -177,16 +177,14 @@ static int atmel_ecdh_compute_shared_secret(struct kpp_request *req) work_data->client = ctx->client; ret = atmel_i2c_init_ecdh_cmd(&work_data->cmd, req->src); - if (ret) - goto free_work_data; + if (ret) { + kfree(work_data); + return ret; + } atmel_i2c_enqueue(work_data, atmel_ecdh_done, req); return -EINPROGRESS; - -free_work_data: - kfree(work_data); - return ret; } static struct i2c_client *atmel_ecc_i2c_client_alloc(void) @@ -348,6 +346,7 @@ static void atmel_ecc_remove(struct i2c_client *client) static const struct of_device_id atmel_ecc_dt_ids[] = { { .compatible = "atmel,atecc508a", }, + { .compatible = "atmel,atecc608a", }, { .compatible = "atmel,atecc608b", }, { } }; @@ -355,6 +354,7 @@ MODULE_DEVICE_TABLE(of, atmel_ecc_dt_ids); static const struct i2c_device_id atmel_ecc_id[] = { { .name = "atecc508a" }, + { .name = "atecc608a" }, { .name = "atecc608b" }, { } }; diff --git a/drivers/crypto/atmel-sha.c b/drivers/crypto/atmel-sha.c index 48f54b615504..4b883a8dcf30 100644 --- a/drivers/crypto/atmel-sha.c +++ b/drivers/crypto/atmel-sha.c @@ -422,6 +422,9 @@ static int atmel_sha_init(struct ahash_request *req) struct atmel_sha_reqctx *ctx = ahash_request_ctx(req); struct atmel_sha_dev *dd = atmel_sha_find_dev(tctx); + if (!dd) + return -ENODEV; + ctx->dd = dd; ctx->flags = 0; @@ -1203,7 +1206,7 @@ static int atmel_sha_finup(struct ahash_request *req) /* * final() has to be always called to cleanup resources - * even if udpate() failed, except EINPROGRESS + * even if update() failed, except EINPROGRESS */ err2 = atmel_sha_final(req); @@ -1338,7 +1341,7 @@ static int atmel_sha_done(struct atmel_sha_dev *dd) return err; finish: - /* finish curent request */ + /* finish current request */ atmel_sha_finish_req(dd->req, err); return err; @@ -2383,11 +2386,25 @@ static int atmel_sha_authenc_final_done(struct atmel_sha_dev *dd) { struct ahash_request *req = dd->req; struct atmel_sha_authenc_reqctx *authctx = ahash_request_ctx(req); + atmel_aes_authenc_fn_t cb; + struct atmel_aes_dev *aes_dev; size_t i, num_words = authctx->digestlen / sizeof(u32); for (i = 0; i < num_words; ++i) authctx->digest[i] = atmel_sha_read(dd, SHA_REG_DIGEST(i)); + if (!dd->is_async) { + /* + * Return the AES finalizer's status directly for synchronous requests. + * The ahash callback cannot propagate it. + */ + cb = authctx->cb; + aes_dev = authctx->aes_dev; + dd->force_complete = false; + (void)atmel_sha_complete(dd, 0); + return cb(aes_dev, 0, false); + } + return atmel_sha_complete(dd, 0); } diff --git a/drivers/crypto/atmel-tdes.c b/drivers/crypto/atmel-tdes.c index ffea1db74651..6b561b333ac6 100644 --- a/drivers/crypto/atmel-tdes.c +++ b/drivers/crypto/atmel-tdes.c @@ -308,45 +308,33 @@ static int atmel_tdes_crypt_pdc_stop(struct atmel_tdes_dev *dd) static int atmel_tdes_buff_init(struct atmel_tdes_dev *dd) { - int err = -ENOMEM; - dd->buf_in = (void *)__get_free_page(GFP_KERNEL); dd->buf_out = (void *)__get_free_page(GFP_KERNEL); - dd->buflen = PAGE_SIZE; - dd->buflen &= ~(DES_BLOCK_SIZE - 1); + dd->buflen = PAGE_SIZE & ~(DES_BLOCK_SIZE - 1); if (!dd->buf_in || !dd->buf_out) { - dev_dbg(dd->dev, "unable to alloc pages.\n"); + dev_err(dd->dev, "failed to allocate DMA buffers\n"); goto err_alloc; } - /* MAP here */ - dd->dma_addr_in = dma_map_single(dd->dev, dd->buf_in, - dd->buflen, DMA_TO_DEVICE); - err = dma_mapping_error(dd->dev, dd->dma_addr_in); - if (err) { - dev_dbg(dd->dev, "dma %zd bytes error\n", dd->buflen); - goto err_map_in; - } + dd->dma_addr_in = dma_map_single(dd->dev, dd->buf_in, dd->buflen, DMA_TO_DEVICE); + if (dma_mapping_error(dd->dev, dd->dma_addr_in)) + goto err_map; - dd->dma_addr_out = dma_map_single(dd->dev, dd->buf_out, - dd->buflen, DMA_FROM_DEVICE); - err = dma_mapping_error(dd->dev, dd->dma_addr_out); - if (err) { - dev_dbg(dd->dev, "dma %zd bytes error\n", dd->buflen); - goto err_map_out; + dd->dma_addr_out = dma_map_single(dd->dev, dd->buf_out, dd->buflen, DMA_FROM_DEVICE); + if (dma_mapping_error(dd->dev, dd->dma_addr_out)) { + dma_unmap_single(dd->dev, dd->dma_addr_in, dd->buflen, DMA_TO_DEVICE); + goto err_map; } return 0; -err_map_out: - dma_unmap_single(dd->dev, dd->dma_addr_in, dd->buflen, - DMA_TO_DEVICE); -err_map_in: +err_map: + dev_err(dd->dev, "failed to map %zu bytes for DMA\n", dd->buflen); err_alloc: free_page((unsigned long)dd->buf_out); free_page((unsigned long)dd->buf_in); - return err; + return -ENOMEM; } static void atmel_tdes_buff_cleanup(struct atmel_tdes_dev *dd) @@ -361,18 +349,9 @@ static void atmel_tdes_buff_cleanup(struct atmel_tdes_dev *dd) static int atmel_tdes_crypt_pdc(struct atmel_tdes_dev *dd, dma_addr_t dma_addr_in, - dma_addr_t dma_addr_out, int length) + dma_addr_t dma_addr_out) { - int len32; - - dd->dma_size = length; - - if (!(dd->flags & TDES_FLAGS_FAST)) { - dma_sync_single_for_device(dd->dev, dma_addr_in, length, - DMA_TO_DEVICE); - } - - len32 = DIV_ROUND_UP(length, sizeof(u32)); + u32 len32 = DIV_ROUND_UP(dd->dma_size, sizeof(u32)); atmel_tdes_write(dd, TDES_PTCR, TDES_PTCR_TXTDIS|TDES_PTCR_RXTDIS); atmel_tdes_write(dd, TDES_TPR, dma_addr_in); @@ -391,46 +370,34 @@ static int atmel_tdes_crypt_pdc(struct atmel_tdes_dev *dd, static int atmel_tdes_crypt_dma(struct atmel_tdes_dev *dd, dma_addr_t dma_addr_in, - dma_addr_t dma_addr_out, int length) + dma_addr_t dma_addr_out) { - struct scatterlist sg[2]; - struct dma_async_tx_descriptor *in_desc, *out_desc; - enum dma_slave_buswidth addr_width; - - dd->dma_size = length; - - if (!(dd->flags & TDES_FLAGS_FAST)) { - dma_sync_single_for_device(dd->dev, dma_addr_in, length, - DMA_TO_DEVICE); - } + struct scatterlist sg_in, sg_out; + struct dma_async_tx_descriptor *in_desc, *out_desc; - addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; - - dd->dma_lch_in.dma_conf.dst_addr_width = addr_width; - dd->dma_lch_out.dma_conf.src_addr_width = addr_width; + dd->dma_lch_in.dma_conf.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + dd->dma_lch_out.dma_conf.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; dmaengine_slave_config(dd->dma_lch_in.chan, &dd->dma_lch_in.dma_conf); dmaengine_slave_config(dd->dma_lch_out.chan, &dd->dma_lch_out.dma_conf); dd->flags |= TDES_FLAGS_DMA; - sg_init_table(&sg[0], 1); - sg_dma_address(&sg[0]) = dma_addr_in; - sg_dma_len(&sg[0]) = length; + sg_init_table(&sg_in, 1); + sg_dma_address(&sg_in) = dma_addr_in; + sg_dma_len(&sg_in) = dd->dma_size; - sg_init_table(&sg[1], 1); - sg_dma_address(&sg[1]) = dma_addr_out; - sg_dma_len(&sg[1]) = length; + sg_init_table(&sg_out, 1); + sg_dma_address(&sg_out) = dma_addr_out; + sg_dma_len(&sg_out) = dd->dma_size; - in_desc = dmaengine_prep_slave_sg(dd->dma_lch_in.chan, &sg[0], - 1, DMA_MEM_TO_DEV, - DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + in_desc = dmaengine_prep_slave_sg(dd->dma_lch_in.chan, &sg_in, 1, DMA_MEM_TO_DEV, + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); if (!in_desc) return -EINVAL; - out_desc = dmaengine_prep_slave_sg(dd->dma_lch_out.chan, &sg[1], - 1, DMA_DEV_TO_MEM, - DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + out_desc = dmaengine_prep_slave_sg(dd->dma_lch_out.chan, &sg_out, 1, DMA_DEV_TO_MEM, + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); if (!out_desc) return -EINVAL; @@ -494,13 +461,19 @@ static int atmel_tdes_crypt_start(struct atmel_tdes_dev *dd) } dd->total -= count; + dd->dma_size = count; + + if (!fast) { + dma_sync_single_for_device(dd->dev, addr_in, dd->dma_size, DMA_TO_DEVICE); + dma_sync_single_for_device(dd->dev, addr_out, dd->dma_size, DMA_FROM_DEVICE); + } if (dd->caps.has_dma) - err = atmel_tdes_crypt_dma(dd, addr_in, addr_out, count); + err = atmel_tdes_crypt_dma(dd, addr_in, addr_out); else - err = atmel_tdes_crypt_pdc(dd, addr_in, addr_out, count); + err = atmel_tdes_crypt_pdc(dd, addr_in, addr_out); - if (err && (dd->flags & TDES_FLAGS_FAST)) { + if (err && fast) { dma_unmap_sg(dd->dev, dd->in_sg, 1, DMA_TO_DEVICE); dma_unmap_sg(dd->dev, dd->out_sg, 1, DMA_FROM_DEVICE); } @@ -660,7 +633,7 @@ static int atmel_tdes_dma_init(struct atmel_tdes_dev *dd) dd->dma_lch_in.chan = dma_request_chan(dd->dev, "tx"); if (IS_ERR(dd->dma_lch_in.chan)) { ret = PTR_ERR(dd->dma_lch_in.chan); - goto err_dma_in; + goto err_dma; } dd->dma_lch_in.dma_conf.dst_addr = dd->phys_base + @@ -676,7 +649,8 @@ static int atmel_tdes_dma_init(struct atmel_tdes_dev *dd) dd->dma_lch_out.chan = dma_request_chan(dd->dev, "rx"); if (IS_ERR(dd->dma_lch_out.chan)) { ret = PTR_ERR(dd->dma_lch_out.chan); - goto err_dma_out; + dma_release_channel(dd->dma_lch_in.chan); + goto err_dma; } dd->dma_lch_out.dma_conf.src_addr = dd->phys_base + @@ -691,9 +665,7 @@ static int atmel_tdes_dma_init(struct atmel_tdes_dev *dd) return 0; -err_dma_out: - dma_release_channel(dd->dma_lch_in.chan); -err_dma_in: +err_dma: dev_err(dd->dev, "no DMA channel available\n"); return ret; } @@ -933,7 +905,7 @@ static int atmel_tdes_probe(struct platform_device *pdev) struct resource *tdes_res; int err; - tdes_dd = devm_kmalloc(&pdev->dev, sizeof(*tdes_dd), GFP_KERNEL); + tdes_dd = devm_kzalloc(&pdev->dev, sizeof(*tdes_dd), GFP_KERNEL); if (!tdes_dd) return -ENOMEM; diff --git a/drivers/crypto/caam/caamalg_qi.c b/drivers/crypto/caam/caamalg_qi.c index aa779caacfe5..2f2682c8bcd8 100644 --- a/drivers/crypto/caam/caamalg_qi.c +++ b/drivers/crypto/caam/caamalg_qi.c @@ -637,6 +637,8 @@ static int skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key, ctx->cdata.keylen = keylen; ctx->cdata.key_virt = key; ctx->cdata.key_inline = true; + ctx->cdata.plain_keylen = keylen; + ctx->cdata.key_cmd_opt = 0; /* skcipher encrypt, decrypt shared descriptors */ cnstr_shdsc_skcipher_encap(ctx->sh_desc_enc, &ctx->cdata, ivsize, diff --git a/drivers/crypto/caam/caamalg_qi2.c b/drivers/crypto/caam/caamalg_qi2.c index 6b47bcc16a50..c95afcb2c751 100644 --- a/drivers/crypto/caam/caamalg_qi2.c +++ b/drivers/crypto/caam/caamalg_qi2.c @@ -26,7 +26,7 @@ #include <crypto/xts.h> #include <linux/unaligned.h> -#define CAAM_CRA_PRIORITY 2000 +#define CAAM_CRA_PRIORITY 100 /* max key is sum of AES_MAX_KEY_SIZE, max split key size */ #define CAAM_MAX_KEY_SIZE (AES_MAX_KEY_SIZE + CTR_RFC3686_NONCE_SIZE + \ @@ -961,6 +961,8 @@ static int skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key, ctx->cdata.keylen = keylen; ctx->cdata.key_virt = key; ctx->cdata.key_inline = true; + ctx->cdata.plain_keylen = keylen; + ctx->cdata.key_cmd_opt = 0; /* skcipher_encrypt shared descriptor */ flc = &ctx->flc[ENCRYPT]; @@ -5041,11 +5043,22 @@ static int __cold dpaa2_dpseci_setup(struct fsl_mc_device *ls_dev) dev_info(dev, "dpseci v%d.%d\n", priv->major_ver, priv->minor_ver); if (DPSECI_VER(priv->major_ver, priv->minor_ver) > DPSECI_VER(5, 3)) { - err = dpseci_reset(priv->mc_io, 0, ls_dev->mc_handle); + int enabled; + + err = dpseci_is_enabled(priv->mc_io, 0, ls_dev->mc_handle, + &enabled); if (err) { - dev_err(dev, "dpseci_reset() failed\n"); + dev_err(dev, "dpseci_is_enabled() failed\n"); goto err_get_vers; } + + if (enabled) { + err = dpseci_reset(priv->mc_io, 0, ls_dev->mc_handle); + if (err) { + dev_err(dev, "dpseci_reset() failed\n"); + goto err_get_vers; + } + } } err = dpseci_get_attributes(priv->mc_io, 0, ls_dev->mc_handle, diff --git a/drivers/crypto/caam/caampkc.c b/drivers/crypto/caam/caampkc.c index cb001aa1de66..ac515ed8c575 100644 --- a/drivers/crypto/caam/caampkc.c +++ b/drivers/crypto/caam/caampkc.c @@ -1033,16 +1033,22 @@ static int caam_rsa_set_priv_key_form(struct caam_rsa_ctx *ctx, free_dq: kfree_sensitive(rsa_key->dq); + rsa_key->dq = NULL; free_dp: kfree_sensitive(rsa_key->dp); + rsa_key->dp = NULL; free_tmp2: kfree_sensitive(rsa_key->tmp2); + rsa_key->tmp2 = NULL; free_tmp1: kfree_sensitive(rsa_key->tmp1); + rsa_key->tmp1 = NULL; free_q: kfree_sensitive(rsa_key->q); + rsa_key->q = NULL; free_p: kfree_sensitive(rsa_key->p); + rsa_key->p = NULL; return -ENOMEM; } diff --git a/drivers/crypto/cavium/cpt/cptpf_main.c b/drivers/crypto/cavium/cpt/cptpf_main.c index 9358c1c041d4..4234f9f156a3 100644 --- a/drivers/crypto/cavium/cpt/cptpf_main.c +++ b/drivers/crypto/cavium/cpt/cptpf_main.c @@ -90,19 +90,19 @@ static void cpt_configure_group(struct cpt_device *cpt, u8 grp, static void cpt_disable_mbox_interrupts(struct cpt_device *cpt) { - /* Clear mbox(0) interupts for all vfs */ + /* Clear mbox(0) interrupts for all vfs */ cpt_write_csr64(cpt->reg_base, CPTX_PF_MBOX_ENA_W1CX(0, 0), ~0ull); } static void cpt_disable_ecc_interrupts(struct cpt_device *cpt) { - /* Clear ecc(0) interupts for all vfs */ + /* Clear ecc(0) interrupts for all vfs */ cpt_write_csr64(cpt->reg_base, CPTX_PF_ECC0_ENA_W1C(0), ~0ull); } static void cpt_disable_exec_interrupts(struct cpt_device *cpt) { - /* Clear exec interupts for all vfs */ + /* Clear exec interrupts for all vfs */ cpt_write_csr64(cpt->reg_base, CPTX_PF_EXEC_ENA_W1C(0), ~0ull); } @@ -115,7 +115,7 @@ static void cpt_disable_all_interrupts(struct cpt_device *cpt) static void cpt_enable_mbox_interrupts(struct cpt_device *cpt) { - /* Set mbox(0) interupts for all vfs */ + /* Set mbox(0) interrupts for all vfs */ cpt_write_csr64(cpt->reg_base, CPTX_PF_MBOX_ENA_W1SX(0, 0), ~0ull); } @@ -140,10 +140,10 @@ static int cpt_load_microcode(struct cpt_device *cpt, struct microcode *mcode) */ if (mcode->is_ae) { core = CPT_MAX_SE_CORES; /* start couting from 10 */ - total_cores = CPT_MAX_TOTAL_CORES; /* upto 15 */ + total_cores = CPT_MAX_TOTAL_CORES; /* up to 15 */ } else { core = 0; /* start couting from 0 */ - total_cores = CPT_MAX_SE_CORES; /* upto 9 */ + total_cores = CPT_MAX_SE_CORES; /* up to 9 */ } /* Point to microcode for each core of the group */ diff --git a/drivers/crypto/cavium/cpt/cptvf_main.c b/drivers/crypto/cavium/cpt/cptvf_main.c index db76df14c4a0..e07448098ac0 100644 --- a/drivers/crypto/cavium/cpt/cptvf_main.c +++ b/drivers/crypto/cavium/cpt/cptvf_main.c @@ -417,7 +417,7 @@ static void cptvf_enable_swerr_interrupts(struct cpt_vf *cptvf) vqx_misc_ena.u = cpt_read_csr64(cptvf->reg_base, CPTX_VQX_MISC_ENA_W1S(0, 0)); - /* Set mbox(0) interupts for the requested vf */ + /* Set mbox(0) interrupts for the requested vf */ vqx_misc_ena.s.swerr = 1; cpt_write_csr64(cptvf->reg_base, CPTX_VQX_MISC_ENA_W1S(0, 0), vqx_misc_ena.u); @@ -429,7 +429,7 @@ static void cptvf_enable_mbox_interrupts(struct cpt_vf *cptvf) vqx_misc_ena.u = cpt_read_csr64(cptvf->reg_base, CPTX_VQX_MISC_ENA_W1S(0, 0)); - /* Set mbox(0) interupts for the requested vf */ + /* Set mbox(0) interrupts for the requested vf */ vqx_misc_ena.s.mbox = 1; cpt_write_csr64(cptvf->reg_base, CPTX_VQX_MISC_ENA_W1S(0, 0), vqx_misc_ena.u); diff --git a/drivers/crypto/cavium/cpt/cptvf_mbox.c b/drivers/crypto/cavium/cpt/cptvf_mbox.c index 1267e1eba7e9..9f2ae10bbd60 100644 --- a/drivers/crypto/cavium/cpt/cptvf_mbox.c +++ b/drivers/crypto/cavium/cpt/cptvf_mbox.c @@ -120,7 +120,7 @@ int cptvf_send_vq_size_msg(struct cpt_vf *cptvf) } /* - * Communicate VF group required to PF and get the VQ binded to that group + * Communicate VF group required to PF and get the VQ bound to that group */ int cptvf_send_vf_to_grp_msg(struct cpt_vf *cptvf) { @@ -139,7 +139,7 @@ int cptvf_send_vf_to_grp_msg(struct cpt_vf *cptvf) } /* - * Communicate VF group required to PF and get the VQ binded to that group + * Communicate VF group required to PF and get the VQ bound to that group */ int cptvf_send_vf_priority_msg(struct cpt_vf *cptvf) { diff --git a/drivers/crypto/cavium/nitrox/nitrox_main.c b/drivers/crypto/cavium/nitrox/nitrox_main.c index e474c84d8d38..54b2db6bb5d0 100644 --- a/drivers/crypto/cavium/nitrox/nitrox_main.c +++ b/drivers/crypto/cavium/nitrox/nitrox_main.c @@ -468,7 +468,7 @@ static int nitrox_probe(struct pci_dev *pdev, err = -EIO; goto ioremap_err; } - /* allocate command queus based on cpus, max queues are 64 */ + /* allocate command queues based on cpus, max queues are 64 */ ndev->nr_queues = min_t(u32, MAX_PF_QUEUES, num_online_cpus()); ndev->qlen = qlen; diff --git a/drivers/crypto/ccp/ccp-dev-v3.c b/drivers/crypto/ccp/ccp-dev-v3.c index 60a133e23e5f..d92de4ad31ac 100644 --- a/drivers/crypto/ccp/ccp-dev-v3.c +++ b/drivers/crypto/ccp/ccp-dev-v3.c @@ -506,6 +506,8 @@ e_kthread: kthread_stop(ccp->cmd_q[i].kthread); sp_free_ccp_irq(ccp->sp, ccp); + if (ccp->use_tasklet) + tasklet_kill(&ccp->irq_tasklet); e_pool: for (i = 0; i < ccp->cmd_q_count; i++) @@ -545,6 +547,8 @@ static void ccp_destroy(struct ccp_device *ccp) kthread_stop(ccp->cmd_q[i].kthread); sp_free_ccp_irq(ccp->sp, ccp); + if (ccp->use_tasklet) + tasklet_kill(&ccp->irq_tasklet); for (i = 0; i < ccp->cmd_q_count; i++) dma_pool_destroy(ccp->cmd_q[i].dma_pool); diff --git a/drivers/crypto/ccp/ccp-dev-v5.c b/drivers/crypto/ccp/ccp-dev-v5.c index dcd6aab51e47..dacde9614e8a 100644 --- a/drivers/crypto/ccp/ccp-dev-v5.c +++ b/drivers/crypto/ccp/ccp-dev-v5.c @@ -995,6 +995,8 @@ e_kthread: e_irq: sp_free_ccp_irq(ccp->sp, ccp); + if (ccp->use_tasklet) + tasklet_kill(&ccp->irq_tasklet); e_pool: for (i = 0; i < ccp->cmd_q_count; i++) @@ -1046,6 +1048,8 @@ static void ccp5_destroy(struct ccp_device *ccp) kthread_stop(ccp->cmd_q[i].kthread); sp_free_ccp_irq(ccp->sp, ccp); + if (ccp->use_tasklet) + tasklet_kill(&ccp->irq_tasklet); /* Flush the cmd and backlog queue */ while (!list_empty(&ccp->cmd)) { diff --git a/drivers/crypto/ccp/ccp-dev.c b/drivers/crypto/ccp/ccp-dev.c index 246801912e1a..aff3348b8351 100644 --- a/drivers/crypto/ccp/ccp-dev.c +++ b/drivers/crypto/ccp/ccp-dev.c @@ -30,7 +30,7 @@ #define MAX_CCPS 32 -/* Limit CCP use to a specifed number of queues per device */ +/* Limit CCP use to a specified number of queues per device */ static unsigned int nqueues; module_param(nqueues, uint, 0444); MODULE_PARM_DESC(nqueues, "Number of queues per CCP (minimum 1; default: all available)"); diff --git a/drivers/crypto/ccp/dbc.c b/drivers/crypto/ccp/dbc.c index 410084a9039c..4db49a14550c 100644 --- a/drivers/crypto/ccp/dbc.c +++ b/drivers/crypto/ccp/dbc.c @@ -236,6 +236,8 @@ int dbc_dev_init(struct psp_device *psp) goto cleanup_mbox; } + mutex_init(&dbc_dev->ioctl_mutex); + dbc_dev->char_dev.minor = MISC_DYNAMIC_MINOR; dbc_dev->char_dev.name = "dbc"; dbc_dev->char_dev.fops = &dbc_fops; @@ -244,8 +246,6 @@ int dbc_dev_init(struct psp_device *psp) if (ret) goto cleanup_mbox; - mutex_init(&dbc_dev->ioctl_mutex); - return 0; cleanup_mbox: diff --git a/drivers/crypto/ccp/sfs.c b/drivers/crypto/ccp/sfs.c index a4777839790b..530141f8bc74 100644 --- a/drivers/crypto/ccp/sfs.c +++ b/drivers/crypto/ccp/sfs.c @@ -111,13 +111,13 @@ static long sfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) struct sfs_device *sfs_dev; int ret = 0; + guard(mutex)(&sfs_ioctl_mutex); + if (!psp_master || !psp_master->sfs_data) return -ENODEV; sfs_dev = psp_master->sfs_data; - guard(mutex)(&sfs_ioctl_mutex); - switch (cmd) { case SFSIOCFWVERS: dev_dbg(sfs_dev->dev, "in SFSIOCFWVERS\n"); @@ -191,8 +191,11 @@ static void sfs_exit(struct kref *ref) void sfs_dev_destroy(struct psp_device *psp) { - struct sfs_device *sfs_dev = psp->sfs_data; + struct sfs_device *sfs_dev; + + guard(mutex)(&sfs_ioctl_mutex); + sfs_dev = psp->sfs_data; if (!sfs_dev) return; diff --git a/drivers/crypto/ccp/sp-platform.c b/drivers/crypto/ccp/sp-platform.c index 3f9843fa7782..c7ac840cbe13 100644 --- a/drivers/crypto/ccp/sp-platform.c +++ b/drivers/crypto/ccp/sp-platform.c @@ -40,8 +40,8 @@ static const struct sp_dev_vdata dev_vdata[] = { }; static const struct acpi_device_id sp_acpi_match[] = { - { "AMDI0C00", (kernel_ulong_t)&dev_vdata[0] }, - { }, + { .id = "AMDI0C00", .driver_data = (kernel_ulong_t)&dev_vdata[0] }, + { } }; MODULE_DEVICE_TABLE(acpi, sp_acpi_match); diff --git a/drivers/crypto/ccree/cc_aead.c b/drivers/crypto/ccree/cc_aead.c index 088c4603047f..d57a98f89e53 100644 --- a/drivers/crypto/ccree/cc_aead.c +++ b/drivers/crypto/ccree/cc_aead.c @@ -226,8 +226,8 @@ static void cc_aead_complete(struct device *dev, void *cc_req, int err) goto done; if (areq_ctx->gen_ctx.op_type == DRV_CRYPTO_DIRECTION_DECRYPT) { - if (memcmp(areq_ctx->mac_buf, areq_ctx->icv_virt_addr, - ctx->authsize) != 0) { + if (crypto_memneq(areq_ctx->mac_buf, areq_ctx->icv_virt_addr, + ctx->authsize)) { dev_dbg(dev, "Payload authentication failure, (auth-size=%d, cipher=%d)\n", ctx->authsize, ctx->cipher_mode); /* In case of payload authentication failure, MUST NOT diff --git a/drivers/crypto/ccree/cc_buffer_mgr.c b/drivers/crypto/ccree/cc_buffer_mgr.c index dc7e0cd51c25..a592f5ec1b6a 100644 --- a/drivers/crypto/ccree/cc_buffer_mgr.c +++ b/drivers/crypto/ccree/cc_buffer_mgr.c @@ -717,7 +717,7 @@ static void cc_prepare_aead_data_mlli(struct cc_drvdata *drvdata, } } else { /* Contig. ICV */ sg = &areq_ctx->src_sgl[areq_ctx->src.nents - 1]; - /*Should hanlde if the sg is not contig.*/ + /*Should handle if the sg is not contig.*/ areq_ctx->icv_dma_addr = sg_dma_address(sg) + (*src_last_bytes - authsize); areq_ctx->icv_virt_addr = sg_virt(sg) + @@ -749,7 +749,7 @@ static void cc_prepare_aead_data_mlli(struct cc_drvdata *drvdata, } else { /* Contig. ICV */ sg = &areq_ctx->src_sgl[areq_ctx->src.nents - 1]; - /*Should hanlde if the sg is not contig.*/ + /*Should handle if the sg is not contig.*/ areq_ctx->icv_dma_addr = sg_dma_address(sg) + (*src_last_bytes - authsize); areq_ctx->icv_virt_addr = sg_virt(sg) + diff --git a/drivers/crypto/ccree/cc_pm.c b/drivers/crypto/ccree/cc_pm.c index bbd118f8de0e..666866119588 100644 --- a/drivers/crypto/ccree/cc_pm.c +++ b/drivers/crypto/ccree/cc_pm.c @@ -66,13 +66,7 @@ const struct dev_pm_ops ccree_pm = { int cc_pm_get(struct device *dev) { - int rc = pm_runtime_get_sync(dev); - if (rc < 0) { - pm_runtime_put_noidle(dev); - return rc; - } - - return 0; + return pm_runtime_resume_and_get(dev); } void cc_pm_put_suspend(struct device *dev) diff --git a/drivers/crypto/chelsio/chcr_algo.c b/drivers/crypto/chelsio/chcr_algo.c index 6dec42282768..e2f2b2a6200e 100644 --- a/drivers/crypto/chelsio/chcr_algo.c +++ b/drivers/crypto/chelsio/chcr_algo.c @@ -1605,7 +1605,7 @@ static struct sk_buff *create_hash_wr(struct ahash_request *req, req_ctx->hctx_wr.dma_addr = 0; } chcr_add_hash_src_ent(req, ulptx, param); - /* Request upto max wr size */ + /* Request up to max wr size */ temp = param->kctx_len + DUMMY_BYTES + (req_ctx->hctx_wr.imm ? (param->sg_len + param->bfr_len) : 0); atomic_inc(&adap->chcr_stats.digest_rqst); diff --git a/drivers/crypto/gemini/sl3516-ce-cipher.c b/drivers/crypto/gemini/sl3516-ce-cipher.c index 02ec4282333b..eba46aebf176 100644 --- a/drivers/crypto/gemini/sl3516-ce-cipher.c +++ b/drivers/crypto/gemini/sl3516-ce-cipher.c @@ -331,13 +331,12 @@ int sl3516_ce_cipher_init(struct crypto_tfm *tfm) crypto_tfm_alg_driver_name(&sktfm->base), crypto_tfm_alg_driver_name(crypto_skcipher_tfm(op->fallback_tfm))); - err = pm_runtime_get_sync(op->ce->dev); + err = pm_runtime_resume_and_get(op->ce->dev); if (err < 0) goto error_pm; return 0; error_pm: - pm_runtime_put_noidle(op->ce->dev); crypto_free_skcipher(op->fallback_tfm); return err; } diff --git a/drivers/crypto/gemini/sl3516-ce-rng.c b/drivers/crypto/gemini/sl3516-ce-rng.c index 76931ec1cec5..19af03b03e42 100644 --- a/drivers/crypto/gemini/sl3516-ce-rng.c +++ b/drivers/crypto/gemini/sl3516-ce-rng.c @@ -24,11 +24,9 @@ static int sl3516_ce_rng_read(struct hwrng *rng, void *buf, size_t max, bool wai ce->hwrng_stat_bytes += max; #endif - err = pm_runtime_get_sync(ce->dev); - if (err < 0) { - pm_runtime_put_noidle(ce->dev); + err = pm_runtime_resume_and_get(ce->dev); + if (err < 0) return err; - } while (read < max) { *data = readl(ce->base + IPSEC_RAND_NUM_REG); diff --git a/drivers/crypto/hisilicon/Kconfig b/drivers/crypto/hisilicon/Kconfig index aeff08ccbadd..e38a71d96201 100644 --- a/drivers/crypto/hisilicon/Kconfig +++ b/drivers/crypto/hisilicon/Kconfig @@ -1,19 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 -config CRYPTO_DEV_HISI_SEC - tristate "Support for Hisilicon SEC crypto block cipher accelerator" - select CRYPTO_SKCIPHER - select CRYPTO_ALGAPI - select CRYPTO_LIB_DES - select SG_SPLIT - depends on ARM64 || COMPILE_TEST - depends on HAS_IOMEM - help - Support for Hisilicon SEC Engine in Hip06 and Hip07 - - To compile this as a module, choose M here: the module - will be called hisi_sec. - config CRYPTO_DEV_HISI_SEC2 tristate "Support for HiSilicon SEC2 crypto block cipher accelerator" select CRYPTO_SKCIPHER diff --git a/drivers/crypto/hisilicon/Makefile b/drivers/crypto/hisilicon/Makefile index e1068ee9f973..a62965be8633 100644 --- a/drivers/crypto/hisilicon/Makefile +++ b/drivers/crypto/hisilicon/Makefile @@ -1,6 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_CRYPTO_DEV_HISI_HPRE) += hpre/ -obj-$(CONFIG_CRYPTO_DEV_HISI_SEC) += sec/ obj-$(CONFIG_CRYPTO_DEV_HISI_SEC2) += sec2/ obj-$(CONFIG_CRYPTO_DEV_HISI_QM) += hisi_qm.o hisi_qm-objs = qm.o sgl.o debugfs.o diff --git a/drivers/crypto/hisilicon/hpre/hpre.h b/drivers/crypto/hisilicon/hpre/hpre.h index 021dbd9a1d48..f73d01f6da87 100644 --- a/drivers/crypto/hisilicon/hpre/hpre.h +++ b/drivers/crypto/hisilicon/hpre/hpre.h @@ -70,7 +70,6 @@ struct hpre_debug { struct hpre { struct hisi_qm qm; struct hpre_debug debug; - unsigned long status; }; enum hpre_alg_type { diff --git a/drivers/crypto/hisilicon/hpre/hpre_crypto.c b/drivers/crypto/hisilicon/hpre/hpre_crypto.c index 09077abbf6ad..66a276786a7d 100644 --- a/drivers/crypto/hisilicon/hpre/hpre_crypto.c +++ b/drivers/crypto/hisilicon/hpre/hpre_crypto.c @@ -21,19 +21,15 @@ struct hpre_ctx; #define HPRE_CRYPTO_ALG_PRI 1000 #define HPRE_ALIGN_SZ 64 #define HPRE_BITS_2_BYTES_SHIFT 3 -#define HPRE_RSA_512BITS_KSZ 64 -#define HPRE_RSA_1536BITS_KSZ 192 #define HPRE_CRT_PRMS 5 #define HPRE_CRT_Q 2 #define HPRE_CRT_P 3 #define HPRE_CRT_INV 4 #define HPRE_DH_G_FLAG 0x02 #define HPRE_TRY_SEND_TIMES 100 -#define HPRE_INVLD_REQ_ID (-1) #define HPRE_SQE_ALG_BITS 5 #define HPRE_SQE_DONE_SHIFT 30 -#define HPRE_DH_MAX_P_SZ 512 #define HPRE_DFX_SEC_TO_US 1000000 #define HPRE_DFX_US_TO_NS 1000 @@ -56,7 +52,6 @@ struct hpre_ctx; #define HPRE_DRV_RSA_MASK_CAP BIT(0) #define HPRE_DRV_DH_MASK_CAP BIT(1) #define HPRE_DRV_ECDH_MASK_CAP BIT(2) -#define HPRE_DRV_X25519_MASK_CAP BIT(5) static DEFINE_MUTEX(hpre_algs_lock); static unsigned int hpre_available_devs; @@ -135,9 +130,9 @@ struct hpre_asym_request { struct kpp_request *dh; struct kpp_request *ecdh; } areq; - int err; hpre_cb cb; struct timespec64 req_time; + u32 flags; }; static inline unsigned int hpre_align_sz(void) @@ -186,6 +181,7 @@ static int hpre_prepare_dma_buf(struct hpre_asym_request *hpre_req, struct scatterlist *data, unsigned int len, int is_src, dma_addr_t *tmp) { + gfp_t gfp = hpre_req->flags & CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL : GFP_ATOMIC; struct hpre_ctx *ctx = hpre_req->ctx; struct device *dev = ctx->dev; void *ptr; @@ -195,7 +191,7 @@ static int hpre_prepare_dma_buf(struct hpre_asym_request *hpre_req, if (unlikely(shift < 0)) return -EINVAL; - ptr = dma_alloc_coherent(dev, ctx->key_sz, tmp, GFP_ATOMIC); + ptr = dma_alloc_coherent(dev, ctx->key_sz, tmp, gfp); if (unlikely(!ptr)) return -ENOMEM; @@ -419,6 +415,7 @@ static int hpre_msg_request_set(struct hpre_ctx *ctx, void *req, bool is_rsa) h_req = PTR_ALIGN(tmp, hpre_align_sz()); h_req->cb = hpre_rsa_cb; h_req->areq.rsa = akreq; + h_req->flags = akreq->base.flags; msg = &h_req->req; memset(msg, 0, sizeof(*msg)); } else { @@ -433,6 +430,7 @@ static int hpre_msg_request_set(struct hpre_ctx *ctx, void *req, bool is_rsa) h_req = PTR_ALIGN(tmp, hpre_align_sz()); h_req->cb = hpre_dh_cb; h_req->areq.dh = kreq; + h_req->flags = kreq->base.flags; msg = &h_req->req; memset(msg, 0, sizeof(*msg)); msg->key = cpu_to_le64(ctx->dh.dma_xa_p); @@ -720,7 +718,7 @@ static void hpre_dh_exit_tfm(struct crypto_kpp *tfm) static void hpre_rsa_drop_leading_zeros(const char **ptr, size_t *len) { - while (!**ptr && *len) { + while (*len && !**ptr) { (*ptr)++; (*len)--; } @@ -1407,8 +1405,6 @@ static void hpre_ecdh_hw_data_clr_all(struct hpre_ctx *ctx, if (unlikely(dma_mapping_error(dev, dma))) return; - if (req->dst) - dma_free_coherent(dev, ctx->key_sz << 1, req->dst, dma); if (dst) dma_unmap_single(dev, dma, ctx->key_sz << 1, DMA_FROM_DEVICE); } @@ -1452,13 +1448,14 @@ static int hpre_ecdh_msg_request_set(struct hpre_ctx *ctx, if (req->dst_len < ctx->key_sz << 1) { req->dst_len = ctx->key_sz << 1; - return -EINVAL; + return -EOVERFLOW; } tmp = kpp_request_ctx(req); h_req = PTR_ALIGN(tmp, hpre_align_sz()); h_req->cb = hpre_ecdh_cb; h_req->areq.ecdh = req; + h_req->flags = req->base.flags; msg = &h_req->req; memset(msg, 0, sizeof(*msg)); msg->in = cpu_to_le64(DMA_MAPPING_ERROR); @@ -1477,6 +1474,7 @@ static int hpre_ecdh_msg_request_set(struct hpre_ctx *ctx, static int hpre_ecdh_src_data_init(struct hpre_asym_request *hpre_req, struct scatterlist *data, unsigned int len) { + gfp_t gfp = hpre_req->flags & CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL : GFP_ATOMIC; struct hpre_sqe *msg = &hpre_req->req; struct hpre_ctx *ctx = hpre_req->ctx; struct device *dev = ctx->dev; @@ -1490,7 +1488,7 @@ static int hpre_ecdh_src_data_init(struct hpre_asym_request *hpre_req, if (unlikely(shift < 0)) return -EINVAL; - ptr = dma_alloc_coherent(dev, ctx->key_sz << 2, &dma, GFP_KERNEL); + ptr = dma_alloc_coherent(dev, ctx->key_sz << 2, &dma, gfp); if (unlikely(!ptr)) return -ENOMEM; @@ -1512,13 +1510,13 @@ static int hpre_ecdh_dst_data_init(struct hpre_asym_request *hpre_req, struct device *dev = ctx->dev; dma_addr_t dma; - if (unlikely(!data || !sg_is_last(data) || len != ctx->key_sz << 1)) { - dev_err(dev, "data or data length is illegal!\n"); + if (unlikely(!data || !sg_is_last(data))) { + dev_err(dev, "data is illegal!\n"); return -EINVAL; } hpre_req->dst = NULL; - dma = dma_map_single(dev, sg_virt(data), len, DMA_FROM_DEVICE); + dma = dma_map_single(dev, sg_virt(data), ctx->key_sz << 1, DMA_FROM_DEVICE); if (unlikely(dma_mapping_error(dev, dma))) { dev_err(dev, "dma map data err!\n"); return -ENOMEM; diff --git a/drivers/crypto/hisilicon/hpre/hpre_main.c b/drivers/crypto/hisilicon/hpre/hpre_main.c index b6903fce6071..fd3c34daceb7 100644 --- a/drivers/crypto/hisilicon/hpre/hpre_main.c +++ b/drivers/crypto/hisilicon/hpre/hpre_main.c @@ -16,7 +16,6 @@ #define CAP_FILE_PERMISSION 0444 #define HPRE_CTRL_CNT_CLR_CE_BIT BIT(0) #define HPRE_CTRL_CNT_CLR_CE 0x301000 -#define HPRE_FSM_MAX_CNT 0x301008 #define HPRE_VFG_AXQOS 0x30100c #define HPRE_VFG_AXCACHE 0x301010 #define HPRE_RDCHN_INI_CFG 0x301014 @@ -41,7 +40,6 @@ #define HPRE_HAC_INT_SET 0x301500 #define HPRE_AXI_ERROR_MASK GENMASK(21, 10) #define HPRE_RNG_TIMEOUT_NUM 0x301A34 -#define HPRE_CORE_INT_ENABLE 0 #define HPRE_RDCHN_INI_ST 0x301a00 #define HPRE_CLSTR_BASE 0x302000 #define HPRE_CORE_EN_OFFSET 0x04 @@ -61,8 +59,6 @@ #define HPRE_CORE_ENB (HPRE_CLSTR_BASE + HPRE_CORE_EN_OFFSET) #define HPRE_CORE_INI_CFG (HPRE_CLSTR_BASE + HPRE_CORE_INI_CFG_OFFSET) #define HPRE_CORE_INI_STATUS (HPRE_CLSTR_BASE + HPRE_CORE_INI_STATUS_OFFSET) -#define HPRE_HAC_ECC1_CNT 0x301a04 -#define HPRE_HAC_ECC2_CNT 0x301a08 #define HPRE_HAC_SOURCE_INT 0x301600 #define HPRE_CLSTR_ADDR_INTRVL 0x1000 #define HPRE_CLUSTER_INQURY 0x100 @@ -381,6 +377,14 @@ static const char *hpre_channel_name[HPRE_MAX_CHANNEL_NUM] = { static const struct hisi_qm_err_ini hpre_err_ini; +static inline u8 hpre_get_clusters_num(struct hisi_qm *qm) +{ + u32 cap = qm->cap_tables.dev_cap_table[HPRE_CORE_INFO].cap_val; + + return (cap >> hpre_basic_info[HPRE_CLUSTER_NUM_CAP].shift) & + hpre_basic_info[HPRE_CLUSTER_NUM_CAP].mask; +} + bool hpre_check_alg_support(struct hisi_qm *qm, u32 alg) { u32 cap_val; @@ -557,15 +561,12 @@ static int hpre_set_cluster(struct hisi_qm *qm) struct device *dev = &qm->pdev->dev; u32 cluster_core_mask; unsigned long offset; - u32 hpre_core_info; u8 clusters_num; u32 val = 0; int ret, i; cluster_core_mask = qm->cap_tables.dev_cap_table[HPRE_CORE_EN].cap_val; - hpre_core_info = qm->cap_tables.dev_cap_table[HPRE_CORE_INFO].cap_val; - clusters_num = (hpre_core_info >> hpre_basic_info[HPRE_CLUSTER_NUM_CAP].shift) & - hpre_basic_info[HPRE_CLUSTER_NUM_CAP].mask; + clusters_num = hpre_get_clusters_num(qm); for (i = 0; i < clusters_num; i++) { offset = i * HPRE_CLSTR_ADDR_INTRVL; @@ -659,7 +660,6 @@ static void hpre_enable_clock_gate(struct hisi_qm *qm) { unsigned long offset; u8 clusters_num, i; - u32 hpre_core_info; u32 val; if (qm->ver < QM_HW_V3) @@ -673,9 +673,7 @@ static void hpre_enable_clock_gate(struct hisi_qm *qm) val |= HPRE_PEH_CFG_AUTO_GATE_EN; writel(val, qm->io_base + HPRE_PEH_CFG_AUTO_GATE); - hpre_core_info = qm->cap_tables.dev_cap_table[HPRE_CORE_INFO].cap_val; - clusters_num = (hpre_core_info >> hpre_basic_info[HPRE_CLUSTER_NUM_CAP].shift) & - hpre_basic_info[HPRE_CLUSTER_NUM_CAP].mask; + clusters_num = hpre_get_clusters_num(qm); for (i = 0; i < clusters_num; i++) { offset = (unsigned long)i * HPRE_CLSTR_ADDR_INTRVL; val = readl(qm->io_base + offset + HPRE_CLUSTER_DYN_CTL); @@ -692,7 +690,6 @@ static void hpre_disable_clock_gate(struct hisi_qm *qm) { unsigned long offset; u8 clusters_num, i; - u32 hpre_core_info; u32 val; if (qm->ver < QM_HW_V3) @@ -706,9 +703,7 @@ static void hpre_disable_clock_gate(struct hisi_qm *qm) val &= ~HPRE_PEH_CFG_AUTO_GATE_EN; writel(val, qm->io_base + HPRE_PEH_CFG_AUTO_GATE); - hpre_core_info = qm->cap_tables.dev_cap_table[HPRE_CORE_INFO].cap_val; - clusters_num = (hpre_core_info >> hpre_basic_info[HPRE_CLUSTER_NUM_CAP].shift) & - hpre_basic_info[HPRE_CLUSTER_NUM_CAP].mask; + clusters_num = hpre_get_clusters_num(qm); for (i = 0; i < clusters_num; i++) { offset = (unsigned long)i * HPRE_CLSTR_ADDR_INTRVL; val = readl(qm->io_base + offset + HPRE_CLUSTER_DYN_CTL); @@ -782,14 +777,11 @@ static int hpre_set_user_domain_and_cache(struct hisi_qm *qm) static void hpre_cnt_regs_clear(struct hisi_qm *qm) { unsigned long offset; - u32 hpre_core_info; u8 clusters_num; int i; /* clear clusterX/cluster_ctrl */ - hpre_core_info = qm->cap_tables.dev_cap_table[HPRE_CORE_INFO].cap_val; - clusters_num = (hpre_core_info >> hpre_basic_info[HPRE_CLUSTER_NUM_CAP].shift) & - hpre_basic_info[HPRE_CLUSTER_NUM_CAP].mask; + clusters_num = hpre_get_clusters_num(qm); for (i = 0; i < clusters_num; i++) { offset = HPRE_CLSTR_BASE + i * HPRE_CLSTR_ADDR_INTRVL; writel(0x0, qm->io_base + offset + HPRE_CLUSTER_INQURY); @@ -1072,13 +1064,10 @@ static int hpre_cluster_debugfs_init(struct hisi_qm *qm) char buf[HPRE_DBGFS_VAL_MAX_LEN]; struct debugfs_regset32 *regset; struct dentry *tmp_d; - u32 hpre_core_info; u8 clusters_num; int i, ret; - hpre_core_info = qm->cap_tables.dev_cap_table[HPRE_CORE_INFO].cap_val; - clusters_num = (hpre_core_info >> hpre_basic_info[HPRE_CLUSTER_NUM_CAP].shift) & - hpre_basic_info[HPRE_CLUSTER_NUM_CAP].mask; + clusters_num = hpre_get_clusters_num(qm); for (i = 0; i < clusters_num; i++) { ret = snprintf(buf, HPRE_DBGFS_VAL_MAX_LEN, "cluster%d", i); if (ret >= HPRE_DBGFS_VAL_MAX_LEN) @@ -1234,8 +1223,8 @@ static int hpre_pre_store_cap_reg(struct hisi_qm *qm) return -EINVAL; } - qm->cap_tables.dev_cap_table = hpre_cap; qm->cap_tables.dev_cap_size = size; + qm->cap_tables.dev_cap_table = hpre_cap; return 0; } @@ -1308,13 +1297,10 @@ static int hpre_show_last_regs_init(struct hisi_qm *qm) int com_dfx_regs_num = ARRAY_SIZE(hpre_com_dfx_regs); struct qm_debug *debug = &qm->debug; void __iomem *io_base; - u32 hpre_core_info; u8 clusters_num; int i, j, idx; - hpre_core_info = qm->cap_tables.dev_cap_table[HPRE_CORE_INFO].cap_val; - clusters_num = (hpre_core_info >> hpre_basic_info[HPRE_CLUSTER_NUM_CAP].shift) & - hpre_basic_info[HPRE_CLUSTER_NUM_CAP].mask; + clusters_num = hpre_get_clusters_num(qm); debug->last_words = kcalloc(cluster_dfx_regs_num * clusters_num + com_dfx_regs_num, sizeof(unsigned int), GFP_KERNEL); if (!debug->last_words) @@ -1354,7 +1340,6 @@ static void hpre_show_last_dfx_regs(struct hisi_qm *qm) struct qm_debug *debug = &qm->debug; struct pci_dev *pdev = qm->pdev; void __iomem *io_base; - u32 hpre_core_info; u8 clusters_num; int i, j, idx; u32 val; @@ -1370,9 +1355,7 @@ static void hpre_show_last_dfx_regs(struct hisi_qm *qm) hpre_com_dfx_regs[i].name, debug->last_words[i], val); } - hpre_core_info = qm->cap_tables.dev_cap_table[HPRE_CORE_INFO].cap_val; - clusters_num = (hpre_core_info >> hpre_basic_info[HPRE_CLUSTER_NUM_CAP].shift) & - hpre_basic_info[HPRE_CLUSTER_NUM_CAP].mask; + clusters_num = hpre_get_clusters_num(qm); for (i = 0; i < clusters_num; i++) { io_base = qm->io_base + hpre_cluster_offsets[i]; for (j = 0; j < cluster_dfx_regs_num; j++) { diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c index c01966a4a33f..7d13476451e3 100644 --- a/drivers/crypto/hisilicon/qm.c +++ b/drivers/crypto/hisilicon/qm.c @@ -5743,8 +5743,8 @@ static int qm_pre_store_caps(struct hisi_qm *qm) i, qm->cap_ver); } - qm->cap_tables.qm_cap_table = qm_cap; qm->cap_tables.qm_cap_size = size; + qm->cap_tables.qm_cap_table = qm_cap; return 0; } diff --git a/drivers/crypto/hisilicon/sec/Makefile b/drivers/crypto/hisilicon/sec/Makefile deleted file mode 100644 index a55b698e0c27..000000000000 --- a/drivers/crypto/hisilicon/sec/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_CRYPTO_DEV_HISI_SEC) += hisi_sec.o -hisi_sec-y = sec_algs.o sec_drv.o diff --git a/drivers/crypto/hisilicon/sec/sec_algs.c b/drivers/crypto/hisilicon/sec/sec_algs.c deleted file mode 100644 index 85eecbb40e7e..000000000000 --- a/drivers/crypto/hisilicon/sec/sec_algs.c +++ /dev/null @@ -1,1122 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* Copyright (c) 2016-2017 HiSilicon Limited. */ -#include <linux/crypto.h> -#include <linux/dma-mapping.h> -#include <linux/dmapool.h> -#include <linux/module.h> -#include <linux/mutex.h> -#include <linux/slab.h> - -#include <crypto/aes.h> -#include <crypto/algapi.h> -#include <crypto/internal/des.h> -#include <crypto/skcipher.h> -#include <crypto/xts.h> -#include <crypto/internal/skcipher.h> - -#include "sec_drv.h" - -#define SEC_MAX_CIPHER_KEY 64 -#define SEC_REQ_LIMIT SZ_32M - -struct sec_c_alg_cfg { - unsigned c_alg : 3; - unsigned c_mode : 3; - unsigned key_len : 2; - unsigned c_width : 2; -}; - -static const struct sec_c_alg_cfg sec_c_alg_cfgs[] = { - [SEC_C_DES_ECB_64] = { - .c_alg = SEC_C_ALG_DES, - .c_mode = SEC_C_MODE_ECB, - .key_len = SEC_KEY_LEN_DES, - }, - [SEC_C_DES_CBC_64] = { - .c_alg = SEC_C_ALG_DES, - .c_mode = SEC_C_MODE_CBC, - .key_len = SEC_KEY_LEN_DES, - }, - [SEC_C_3DES_ECB_192_3KEY] = { - .c_alg = SEC_C_ALG_3DES, - .c_mode = SEC_C_MODE_ECB, - .key_len = SEC_KEY_LEN_3DES_3_KEY, - }, - [SEC_C_3DES_ECB_192_2KEY] = { - .c_alg = SEC_C_ALG_3DES, - .c_mode = SEC_C_MODE_ECB, - .key_len = SEC_KEY_LEN_3DES_2_KEY, - }, - [SEC_C_3DES_CBC_192_3KEY] = { - .c_alg = SEC_C_ALG_3DES, - .c_mode = SEC_C_MODE_CBC, - .key_len = SEC_KEY_LEN_3DES_3_KEY, - }, - [SEC_C_3DES_CBC_192_2KEY] = { - .c_alg = SEC_C_ALG_3DES, - .c_mode = SEC_C_MODE_CBC, - .key_len = SEC_KEY_LEN_3DES_2_KEY, - }, - [SEC_C_AES_ECB_128] = { - .c_alg = SEC_C_ALG_AES, - .c_mode = SEC_C_MODE_ECB, - .key_len = SEC_KEY_LEN_AES_128, - }, - [SEC_C_AES_ECB_192] = { - .c_alg = SEC_C_ALG_AES, - .c_mode = SEC_C_MODE_ECB, - .key_len = SEC_KEY_LEN_AES_192, - }, - [SEC_C_AES_ECB_256] = { - .c_alg = SEC_C_ALG_AES, - .c_mode = SEC_C_MODE_ECB, - .key_len = SEC_KEY_LEN_AES_256, - }, - [SEC_C_AES_CBC_128] = { - .c_alg = SEC_C_ALG_AES, - .c_mode = SEC_C_MODE_CBC, - .key_len = SEC_KEY_LEN_AES_128, - }, - [SEC_C_AES_CBC_192] = { - .c_alg = SEC_C_ALG_AES, - .c_mode = SEC_C_MODE_CBC, - .key_len = SEC_KEY_LEN_AES_192, - }, - [SEC_C_AES_CBC_256] = { - .c_alg = SEC_C_ALG_AES, - .c_mode = SEC_C_MODE_CBC, - .key_len = SEC_KEY_LEN_AES_256, - }, - [SEC_C_AES_CTR_128] = { - .c_alg = SEC_C_ALG_AES, - .c_mode = SEC_C_MODE_CTR, - .key_len = SEC_KEY_LEN_AES_128, - }, - [SEC_C_AES_CTR_192] = { - .c_alg = SEC_C_ALG_AES, - .c_mode = SEC_C_MODE_CTR, - .key_len = SEC_KEY_LEN_AES_192, - }, - [SEC_C_AES_CTR_256] = { - .c_alg = SEC_C_ALG_AES, - .c_mode = SEC_C_MODE_CTR, - .key_len = SEC_KEY_LEN_AES_256, - }, - [SEC_C_AES_XTS_128] = { - .c_alg = SEC_C_ALG_AES, - .c_mode = SEC_C_MODE_XTS, - .key_len = SEC_KEY_LEN_AES_128, - }, - [SEC_C_AES_XTS_256] = { - .c_alg = SEC_C_ALG_AES, - .c_mode = SEC_C_MODE_XTS, - .key_len = SEC_KEY_LEN_AES_256, - }, - [SEC_C_NULL] = { - }, -}; - -/* - * Mutex used to ensure safe operation of reference count of - * alg providers - */ -static DEFINE_MUTEX(algs_lock); -static unsigned int active_devs; - -static void sec_alg_skcipher_init_template(struct sec_alg_tfm_ctx *ctx, - struct sec_bd_info *req, - enum sec_cipher_alg alg) -{ - const struct sec_c_alg_cfg *cfg = &sec_c_alg_cfgs[alg]; - - memset(req, 0, sizeof(*req)); - req->w0 |= cfg->c_mode << SEC_BD_W0_C_MODE_S; - req->w1 |= cfg->c_alg << SEC_BD_W1_C_ALG_S; - req->w3 |= cfg->key_len << SEC_BD_W3_C_KEY_LEN_S; - req->w0 |= cfg->c_width << SEC_BD_W0_C_WIDTH_S; - - req->cipher_key_addr_lo = lower_32_bits(ctx->pkey); - req->cipher_key_addr_hi = upper_32_bits(ctx->pkey); -} - -static void sec_alg_skcipher_init_context(struct crypto_skcipher *atfm, - const u8 *key, - unsigned int keylen, - enum sec_cipher_alg alg) -{ - struct crypto_tfm *tfm = crypto_skcipher_tfm(atfm); - struct sec_alg_tfm_ctx *ctx = crypto_tfm_ctx(tfm); - - ctx->cipher_alg = alg; - memcpy(ctx->key, key, keylen); - sec_alg_skcipher_init_template(ctx, &ctx->req_template, - ctx->cipher_alg); -} - -static void sec_free_hw_sgl(struct sec_hw_sgl *hw_sgl, - dma_addr_t psec_sgl, struct sec_dev_info *info) -{ - struct sec_hw_sgl *sgl_current, *sgl_next; - dma_addr_t sgl_next_dma; - - sgl_current = hw_sgl; - while (sgl_current) { - sgl_next = sgl_current->next; - sgl_next_dma = sgl_current->next_sgl; - - dma_pool_free(info->hw_sgl_pool, sgl_current, psec_sgl); - - sgl_current = sgl_next; - psec_sgl = sgl_next_dma; - } -} - -static int sec_alloc_and_fill_hw_sgl(struct sec_hw_sgl **sec_sgl, - dma_addr_t *psec_sgl, - struct scatterlist *sgl, - int count, - struct sec_dev_info *info, - gfp_t gfp) -{ - struct sec_hw_sgl *sgl_current = NULL; - struct sec_hw_sgl *sgl_next; - dma_addr_t sgl_next_dma; - struct scatterlist *sg; - int ret, sge_index, i; - - if (!count) - return -EINVAL; - - for_each_sg(sgl, sg, count, i) { - sge_index = i % SEC_MAX_SGE_NUM; - if (sge_index == 0) { - sgl_next = dma_pool_zalloc(info->hw_sgl_pool, - gfp, &sgl_next_dma); - if (!sgl_next) { - ret = -ENOMEM; - goto err_free_hw_sgls; - } - - if (!sgl_current) { /* First one */ - *psec_sgl = sgl_next_dma; - *sec_sgl = sgl_next; - } else { /* Chained */ - sgl_current->entry_sum_in_sgl = SEC_MAX_SGE_NUM; - sgl_current->next_sgl = sgl_next_dma; - sgl_current->next = sgl_next; - } - sgl_current = sgl_next; - } - sgl_current->sge_entries[sge_index].buf = sg_dma_address(sg); - sgl_current->sge_entries[sge_index].len = sg_dma_len(sg); - sgl_current->data_bytes_in_sgl += sg_dma_len(sg); - } - sgl_current->entry_sum_in_sgl = count % SEC_MAX_SGE_NUM; - sgl_current->next_sgl = 0; - (*sec_sgl)->entry_sum_in_chain = count; - - return 0; - -err_free_hw_sgls: - sec_free_hw_sgl(*sec_sgl, *psec_sgl, info); - *psec_sgl = 0; - - return ret; -} - -static int sec_alg_skcipher_setkey(struct crypto_skcipher *tfm, - const u8 *key, unsigned int keylen, - enum sec_cipher_alg alg) -{ - struct sec_alg_tfm_ctx *ctx = crypto_skcipher_ctx(tfm); - struct device *dev = ctx->queue->dev_info->dev; - - mutex_lock(&ctx->lock); - if (ctx->key) { - /* rekeying */ - memset(ctx->key, 0, SEC_MAX_CIPHER_KEY); - } else { - /* new key */ - ctx->key = dma_alloc_coherent(dev, SEC_MAX_CIPHER_KEY, - &ctx->pkey, GFP_KERNEL); - if (!ctx->key) { - mutex_unlock(&ctx->lock); - return -ENOMEM; - } - } - mutex_unlock(&ctx->lock); - sec_alg_skcipher_init_context(tfm, key, keylen, alg); - - return 0; -} - -static int sec_alg_skcipher_setkey_aes_ecb(struct crypto_skcipher *tfm, - const u8 *key, unsigned int keylen) -{ - enum sec_cipher_alg alg; - - switch (keylen) { - case AES_KEYSIZE_128: - alg = SEC_C_AES_ECB_128; - break; - case AES_KEYSIZE_192: - alg = SEC_C_AES_ECB_192; - break; - case AES_KEYSIZE_256: - alg = SEC_C_AES_ECB_256; - break; - default: - return -EINVAL; - } - - return sec_alg_skcipher_setkey(tfm, key, keylen, alg); -} - -static int sec_alg_skcipher_setkey_aes_cbc(struct crypto_skcipher *tfm, - const u8 *key, unsigned int keylen) -{ - enum sec_cipher_alg alg; - - switch (keylen) { - case AES_KEYSIZE_128: - alg = SEC_C_AES_CBC_128; - break; - case AES_KEYSIZE_192: - alg = SEC_C_AES_CBC_192; - break; - case AES_KEYSIZE_256: - alg = SEC_C_AES_CBC_256; - break; - default: - return -EINVAL; - } - - return sec_alg_skcipher_setkey(tfm, key, keylen, alg); -} - -static int sec_alg_skcipher_setkey_aes_ctr(struct crypto_skcipher *tfm, - const u8 *key, unsigned int keylen) -{ - enum sec_cipher_alg alg; - - switch (keylen) { - case AES_KEYSIZE_128: - alg = SEC_C_AES_CTR_128; - break; - case AES_KEYSIZE_192: - alg = SEC_C_AES_CTR_192; - break; - case AES_KEYSIZE_256: - alg = SEC_C_AES_CTR_256; - break; - default: - return -EINVAL; - } - - return sec_alg_skcipher_setkey(tfm, key, keylen, alg); -} - -static int sec_alg_skcipher_setkey_aes_xts(struct crypto_skcipher *tfm, - const u8 *key, unsigned int keylen) -{ - enum sec_cipher_alg alg; - int ret; - - ret = xts_verify_key(tfm, key, keylen); - if (ret) - return ret; - - switch (keylen) { - case AES_KEYSIZE_128 * 2: - alg = SEC_C_AES_XTS_128; - break; - case AES_KEYSIZE_256 * 2: - alg = SEC_C_AES_XTS_256; - break; - default: - return -EINVAL; - } - - return sec_alg_skcipher_setkey(tfm, key, keylen, alg); -} - -static int sec_alg_skcipher_setkey_des_ecb(struct crypto_skcipher *tfm, - const u8 *key, unsigned int keylen) -{ - return verify_skcipher_des_key(tfm, key) ?: - sec_alg_skcipher_setkey(tfm, key, keylen, SEC_C_DES_ECB_64); -} - -static int sec_alg_skcipher_setkey_des_cbc(struct crypto_skcipher *tfm, - const u8 *key, unsigned int keylen) -{ - return verify_skcipher_des_key(tfm, key) ?: - sec_alg_skcipher_setkey(tfm, key, keylen, SEC_C_DES_CBC_64); -} - -static int sec_alg_skcipher_setkey_3des_ecb(struct crypto_skcipher *tfm, - const u8 *key, unsigned int keylen) -{ - return verify_skcipher_des3_key(tfm, key) ?: - sec_alg_skcipher_setkey(tfm, key, keylen, - SEC_C_3DES_ECB_192_3KEY); -} - -static int sec_alg_skcipher_setkey_3des_cbc(struct crypto_skcipher *tfm, - const u8 *key, unsigned int keylen) -{ - return verify_skcipher_des3_key(tfm, key) ?: - sec_alg_skcipher_setkey(tfm, key, keylen, - SEC_C_3DES_CBC_192_3KEY); -} - -static void sec_alg_free_el(struct sec_request_el *el, - struct sec_dev_info *info) -{ - sec_free_hw_sgl(el->out, el->dma_out, info); - sec_free_hw_sgl(el->in, el->dma_in, info); - kfree(el->sgl_in); - kfree(el->sgl_out); - kfree(el); -} - -/* queuelock must be held */ -static int sec_send_request(struct sec_request *sec_req, struct sec_queue *queue) -{ - struct sec_request_el *el, *temp; - int ret = 0; - - mutex_lock(&sec_req->lock); - list_for_each_entry_safe(el, temp, &sec_req->elements, head) { - /* - * Add to hardware queue only under following circumstances - * 1) Software and hardware queue empty so no chain dependencies - * 2) No dependencies as new IV - (check software queue empty - * to maintain order) - * 3) No dependencies because the mode does no chaining. - * - * In other cases first insert onto the software queue which - * is then emptied as requests complete - */ - if (!queue->havesoftqueue || - (kfifo_is_empty(&queue->softqueue) && - sec_queue_empty(queue))) { - ret = sec_queue_send(queue, &el->req, sec_req); - if (ret == -EAGAIN) { - /* Wait unti we can send then try again */ - /* DEAD if here - should not happen */ - ret = -EBUSY; - goto err_unlock; - } - } else { - kfifo_put(&queue->softqueue, el); - } - } -err_unlock: - mutex_unlock(&sec_req->lock); - - return ret; -} - -static void sec_skcipher_alg_callback(struct sec_bd_info *sec_resp, - struct crypto_async_request *req_base) -{ - struct skcipher_request *skreq = container_of(req_base, - struct skcipher_request, - base); - struct sec_request *sec_req = skcipher_request_ctx(skreq); - struct sec_request *backlog_req; - struct sec_request_el *sec_req_el, *nextrequest; - struct sec_alg_tfm_ctx *ctx = sec_req->tfm_ctx; - struct crypto_skcipher *atfm = crypto_skcipher_reqtfm(skreq); - struct device *dev = ctx->queue->dev_info->dev; - int icv_or_skey_en, ret; - bool done; - - sec_req_el = list_first_entry(&sec_req->elements, struct sec_request_el, - head); - icv_or_skey_en = (sec_resp->w0 & SEC_BD_W0_ICV_OR_SKEY_EN_M) >> - SEC_BD_W0_ICV_OR_SKEY_EN_S; - if (sec_resp->w1 & SEC_BD_W1_BD_INVALID || icv_or_skey_en == 3) { - dev_err(dev, "Got an invalid answer %lu %d\n", - sec_resp->w1 & SEC_BD_W1_BD_INVALID, - icv_or_skey_en); - sec_req->err = -EINVAL; - /* - * We need to muddle on to avoid getting stuck with elements - * on the queue. Error will be reported so requester so - * it should be able to handle appropriately. - */ - } - - spin_lock_bh(&ctx->queue->queuelock); - /* Put the IV in place for chained cases */ - switch (ctx->cipher_alg) { - case SEC_C_AES_CBC_128: - case SEC_C_AES_CBC_192: - case SEC_C_AES_CBC_256: - if (sec_req_el->req.w0 & SEC_BD_W0_DE) - sg_pcopy_to_buffer(sec_req_el->sgl_out, - sg_nents(sec_req_el->sgl_out), - skreq->iv, - crypto_skcipher_ivsize(atfm), - sec_req_el->el_length - - crypto_skcipher_ivsize(atfm)); - else - sg_pcopy_to_buffer(sec_req_el->sgl_in, - sg_nents(sec_req_el->sgl_in), - skreq->iv, - crypto_skcipher_ivsize(atfm), - sec_req_el->el_length - - crypto_skcipher_ivsize(atfm)); - /* No need to sync to the device as coherent DMA */ - break; - case SEC_C_AES_CTR_128: - case SEC_C_AES_CTR_192: - case SEC_C_AES_CTR_256: - crypto_inc(skreq->iv, 16); - break; - default: - /* Do not update */ - break; - } - - if (ctx->queue->havesoftqueue && - !kfifo_is_empty(&ctx->queue->softqueue) && - sec_queue_empty(ctx->queue)) { - ret = kfifo_get(&ctx->queue->softqueue, &nextrequest); - if (ret <= 0) - dev_err(dev, - "Error getting next element from kfifo %d\n", - ret); - else - /* We know there is space so this cannot fail */ - sec_queue_send(ctx->queue, &nextrequest->req, - nextrequest->sec_req); - } else if (!list_empty(&ctx->backlog)) { - /* Need to verify there is room first */ - backlog_req = list_first_entry(&ctx->backlog, - typeof(*backlog_req), - backlog_head); - if (sec_queue_can_enqueue(ctx->queue, - backlog_req->num_elements) || - (ctx->queue->havesoftqueue && - kfifo_avail(&ctx->queue->softqueue) > - backlog_req->num_elements)) { - sec_send_request(backlog_req, ctx->queue); - crypto_request_complete(backlog_req->req_base, - -EINPROGRESS); - list_del(&backlog_req->backlog_head); - } - } - spin_unlock_bh(&ctx->queue->queuelock); - - mutex_lock(&sec_req->lock); - list_del(&sec_req_el->head); - mutex_unlock(&sec_req->lock); - sec_alg_free_el(sec_req_el, ctx->queue->dev_info); - - /* - * Request is done. - * The dance is needed as the lock is freed in the completion - */ - mutex_lock(&sec_req->lock); - done = list_empty(&sec_req->elements); - mutex_unlock(&sec_req->lock); - if (done) { - if (crypto_skcipher_ivsize(atfm)) { - dma_unmap_single(dev, sec_req->dma_iv, - crypto_skcipher_ivsize(atfm), - DMA_TO_DEVICE); - } - dma_unmap_sg(dev, skreq->src, sec_req->len_in, - DMA_BIDIRECTIONAL); - if (skreq->src != skreq->dst) - dma_unmap_sg(dev, skreq->dst, sec_req->len_out, - DMA_BIDIRECTIONAL); - skcipher_request_complete(skreq, sec_req->err); - } -} - -void sec_alg_callback(struct sec_bd_info *resp, void *shadow) -{ - struct sec_request *sec_req = shadow; - - sec_req->cb(resp, sec_req->req_base); -} - -static int sec_alg_alloc_and_calc_split_sizes(int length, size_t **split_sizes, - int *steps, gfp_t gfp) -{ - size_t *sizes; - int i; - - /* Split into suitable sized blocks */ - *steps = roundup(length, SEC_REQ_LIMIT) / SEC_REQ_LIMIT; - sizes = kzalloc_objs(*sizes, *steps, gfp); - if (!sizes) - return -ENOMEM; - - for (i = 0; i < *steps - 1; i++) - sizes[i] = SEC_REQ_LIMIT; - sizes[*steps - 1] = length - SEC_REQ_LIMIT * (*steps - 1); - *split_sizes = sizes; - - return 0; -} - -static int sec_map_and_split_sg(struct scatterlist *sgl, size_t *split_sizes, - int steps, struct scatterlist ***splits, - int **splits_nents, - int sgl_len_in, - struct device *dev, gfp_t gfp) -{ - int ret, count; - - count = dma_map_sg(dev, sgl, sgl_len_in, DMA_BIDIRECTIONAL); - if (!count) - return -EINVAL; - - *splits = kzalloc_objs(struct scatterlist *, steps, gfp); - if (!*splits) { - ret = -ENOMEM; - goto err_unmap_sg; - } - *splits_nents = kzalloc_objs(int, steps, gfp); - if (!*splits_nents) { - ret = -ENOMEM; - goto err_free_splits; - } - - /* output the scatter list before and after this */ - ret = sg_split(sgl, count, 0, steps, split_sizes, - *splits, *splits_nents, gfp); - if (ret) { - ret = -ENOMEM; - goto err_free_splits_nents; - } - - return 0; - -err_free_splits_nents: - kfree(*splits_nents); -err_free_splits: - kfree(*splits); -err_unmap_sg: - dma_unmap_sg(dev, sgl, sgl_len_in, DMA_BIDIRECTIONAL); - - return ret; -} - -/* - * Reverses the sec_map_and_split_sg call for messages not yet added to - * the queues. - */ -static void sec_unmap_sg_on_err(struct scatterlist *sgl, int steps, - struct scatterlist **splits, int *splits_nents, - int sgl_len_in, struct device *dev) -{ - int i; - - for (i = 0; i < steps; i++) - kfree(splits[i]); - kfree(splits_nents); - kfree(splits); - - dma_unmap_sg(dev, sgl, sgl_len_in, DMA_BIDIRECTIONAL); -} - -static struct sec_request_el -*sec_alg_alloc_and_fill_el(struct sec_bd_info *template, int encrypt, - int el_size, bool different_dest, - struct scatterlist *sgl_in, int n_ents_in, - struct scatterlist *sgl_out, int n_ents_out, - struct sec_dev_info *info, gfp_t gfp) -{ - struct sec_request_el *el; - struct sec_bd_info *req; - int ret; - - el = kzalloc_obj(*el, gfp); - if (!el) - return ERR_PTR(-ENOMEM); - el->el_length = el_size; - req = &el->req; - memcpy(req, template, sizeof(*req)); - - req->w0 &= ~SEC_BD_W0_CIPHER_M; - if (encrypt) - req->w0 |= SEC_CIPHER_ENCRYPT << SEC_BD_W0_CIPHER_S; - else - req->w0 |= SEC_CIPHER_DECRYPT << SEC_BD_W0_CIPHER_S; - - req->w0 &= ~SEC_BD_W0_C_GRAN_SIZE_19_16_M; - req->w0 |= ((el_size >> 16) << SEC_BD_W0_C_GRAN_SIZE_19_16_S) & - SEC_BD_W0_C_GRAN_SIZE_19_16_M; - - req->w0 &= ~SEC_BD_W0_C_GRAN_SIZE_21_20_M; - req->w0 |= ((el_size >> 20) << SEC_BD_W0_C_GRAN_SIZE_21_20_S) & - SEC_BD_W0_C_GRAN_SIZE_21_20_M; - - /* Writing whole u32 so no need to take care of masking */ - req->w2 = ((1 << SEC_BD_W2_GRAN_NUM_S) & SEC_BD_W2_GRAN_NUM_M) | - ((el_size << SEC_BD_W2_C_GRAN_SIZE_15_0_S) & - SEC_BD_W2_C_GRAN_SIZE_15_0_M); - - req->w3 &= ~SEC_BD_W3_CIPHER_LEN_OFFSET_M; - req->w1 |= SEC_BD_W1_ADDR_TYPE; - - el->sgl_in = sgl_in; - - ret = sec_alloc_and_fill_hw_sgl(&el->in, &el->dma_in, el->sgl_in, - n_ents_in, info, gfp); - if (ret) - goto err_free_el; - - req->data_addr_lo = lower_32_bits(el->dma_in); - req->data_addr_hi = upper_32_bits(el->dma_in); - - if (different_dest) { - el->sgl_out = sgl_out; - ret = sec_alloc_and_fill_hw_sgl(&el->out, &el->dma_out, - el->sgl_out, - n_ents_out, info, gfp); - if (ret) - goto err_free_hw_sgl_in; - - req->w0 |= SEC_BD_W0_DE; - req->cipher_destin_addr_lo = lower_32_bits(el->dma_out); - req->cipher_destin_addr_hi = upper_32_bits(el->dma_out); - - } else { - req->w0 &= ~SEC_BD_W0_DE; - req->cipher_destin_addr_lo = lower_32_bits(el->dma_in); - req->cipher_destin_addr_hi = upper_32_bits(el->dma_in); - } - - return el; - -err_free_hw_sgl_in: - sec_free_hw_sgl(el->in, el->dma_in, info); -err_free_el: - kfree(el); - - return ERR_PTR(ret); -} - -static int sec_alg_skcipher_crypto(struct skcipher_request *skreq, - bool encrypt) -{ - struct crypto_skcipher *atfm = crypto_skcipher_reqtfm(skreq); - struct crypto_tfm *tfm = crypto_skcipher_tfm(atfm); - struct sec_alg_tfm_ctx *ctx = crypto_tfm_ctx(tfm); - struct sec_queue *queue = ctx->queue; - struct sec_request *sec_req = skcipher_request_ctx(skreq); - struct sec_dev_info *info = queue->dev_info; - int i, ret, steps; - size_t *split_sizes; - struct scatterlist **splits_in; - struct scatterlist **splits_out = NULL; - int *splits_in_nents; - int *splits_out_nents = NULL; - struct sec_request_el *el, *temp; - bool split = skreq->src != skreq->dst; - gfp_t gfp = skreq->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL : GFP_ATOMIC; - - mutex_init(&sec_req->lock); - sec_req->req_base = &skreq->base; - sec_req->err = 0; - /* SGL mapping out here to allow us to break it up as necessary */ - sec_req->len_in = sg_nents(skreq->src); - - ret = sec_alg_alloc_and_calc_split_sizes(skreq->cryptlen, &split_sizes, - &steps, gfp); - if (ret) - return ret; - sec_req->num_elements = steps; - ret = sec_map_and_split_sg(skreq->src, split_sizes, steps, &splits_in, - &splits_in_nents, sec_req->len_in, - info->dev, gfp); - if (ret) - goto err_free_split_sizes; - - if (split) { - sec_req->len_out = sg_nents(skreq->dst); - ret = sec_map_and_split_sg(skreq->dst, split_sizes, steps, - &splits_out, &splits_out_nents, - sec_req->len_out, info->dev, gfp); - if (ret) - goto err_unmap_in_sg; - } - /* Shared info stored in seq_req - applies to all BDs */ - sec_req->tfm_ctx = ctx; - sec_req->cb = sec_skcipher_alg_callback; - INIT_LIST_HEAD(&sec_req->elements); - - /* - * Future optimization. - * In the chaining case we can't use a dma pool bounce buffer - * but in the case where we know there is no chaining we can - */ - if (crypto_skcipher_ivsize(atfm)) { - sec_req->dma_iv = dma_map_single(info->dev, skreq->iv, - crypto_skcipher_ivsize(atfm), - DMA_TO_DEVICE); - if (dma_mapping_error(info->dev, sec_req->dma_iv)) { - ret = -ENOMEM; - goto err_unmap_out_sg; - } - } - - /* Set them all up then queue - cleaner error handling. */ - for (i = 0; i < steps; i++) { - el = sec_alg_alloc_and_fill_el(&ctx->req_template, - encrypt ? 1 : 0, - split_sizes[i], - skreq->src != skreq->dst, - splits_in[i], splits_in_nents[i], - split ? splits_out[i] : NULL, - split ? splits_out_nents[i] : 0, - info, gfp); - if (IS_ERR(el)) { - ret = PTR_ERR(el); - goto err_free_elements; - } - el->req.cipher_iv_addr_lo = lower_32_bits(sec_req->dma_iv); - el->req.cipher_iv_addr_hi = upper_32_bits(sec_req->dma_iv); - el->sec_req = sec_req; - list_add_tail(&el->head, &sec_req->elements); - } - - /* - * Only attempt to queue if the whole lot can fit in the queue - - * we can't successfully cleanup after a partial queing so this - * must succeed or fail atomically. - * - * Big hammer test of both software and hardware queues - could be - * more refined but this is unlikely to happen so no need. - */ - - /* Grab a big lock for a long time to avoid concurrency issues */ - spin_lock_bh(&queue->queuelock); - - /* - * Can go on to queue if we have space in either: - * 1) The hardware queue and no software queue - * 2) The software queue - * AND there is nothing in the backlog. If there is backlog we - * have to only queue to the backlog queue and return busy. - */ - if ((!sec_queue_can_enqueue(queue, steps) && - (!queue->havesoftqueue || - kfifo_avail(&queue->softqueue) > steps)) || - !list_empty(&ctx->backlog)) { - ret = -EBUSY; - if ((skreq->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) { - list_add_tail(&sec_req->backlog_head, &ctx->backlog); - spin_unlock_bh(&queue->queuelock); - goto out; - } - - spin_unlock_bh(&queue->queuelock); - goto err_free_elements; - } - ret = sec_send_request(sec_req, queue); - spin_unlock_bh(&queue->queuelock); - if (ret) - goto err_free_elements; - - ret = -EINPROGRESS; -out: - /* Cleanup - all elements in pointer arrays have been copied */ - kfree(splits_in_nents); - kfree(splits_in); - kfree(splits_out_nents); - kfree(splits_out); - kfree(split_sizes); - return ret; - -err_free_elements: - list_for_each_entry_safe(el, temp, &sec_req->elements, head) { - list_del(&el->head); - sec_alg_free_el(el, info); - } - if (crypto_skcipher_ivsize(atfm)) - dma_unmap_single(info->dev, sec_req->dma_iv, - crypto_skcipher_ivsize(atfm), - DMA_TO_DEVICE); -err_unmap_out_sg: - if (split) - sec_unmap_sg_on_err(skreq->dst, steps, splits_out, - splits_out_nents, sec_req->len_out, - info->dev); -err_unmap_in_sg: - sec_unmap_sg_on_err(skreq->src, steps, splits_in, splits_in_nents, - sec_req->len_in, info->dev); -err_free_split_sizes: - kfree(split_sizes); - - return ret; -} - -static int sec_alg_skcipher_encrypt(struct skcipher_request *req) -{ - return sec_alg_skcipher_crypto(req, true); -} - -static int sec_alg_skcipher_decrypt(struct skcipher_request *req) -{ - return sec_alg_skcipher_crypto(req, false); -} - -static int sec_alg_skcipher_init(struct crypto_skcipher *tfm) -{ - struct sec_alg_tfm_ctx *ctx = crypto_skcipher_ctx(tfm); - - mutex_init(&ctx->lock); - INIT_LIST_HEAD(&ctx->backlog); - crypto_skcipher_set_reqsize(tfm, sizeof(struct sec_request)); - - ctx->queue = sec_queue_alloc_start_safe(); - if (IS_ERR(ctx->queue)) - return PTR_ERR(ctx->queue); - - spin_lock_init(&ctx->queue->queuelock); - ctx->queue->havesoftqueue = false; - - return 0; -} - -static void sec_alg_skcipher_exit(struct crypto_skcipher *tfm) -{ - struct sec_alg_tfm_ctx *ctx = crypto_skcipher_ctx(tfm); - struct device *dev = ctx->queue->dev_info->dev; - - if (ctx->key) { - memzero_explicit(ctx->key, SEC_MAX_CIPHER_KEY); - dma_free_coherent(dev, SEC_MAX_CIPHER_KEY, ctx->key, - ctx->pkey); - } - sec_queue_stop_release(ctx->queue); -} - -static int sec_alg_skcipher_init_with_queue(struct crypto_skcipher *tfm) -{ - struct sec_alg_tfm_ctx *ctx = crypto_skcipher_ctx(tfm); - int ret; - - ret = sec_alg_skcipher_init(tfm); - if (ret) - return ret; - - INIT_KFIFO(ctx->queue->softqueue); - ret = kfifo_alloc(&ctx->queue->softqueue, 512, GFP_KERNEL); - if (ret) { - sec_alg_skcipher_exit(tfm); - return ret; - } - ctx->queue->havesoftqueue = true; - - return 0; -} - -static void sec_alg_skcipher_exit_with_queue(struct crypto_skcipher *tfm) -{ - struct sec_alg_tfm_ctx *ctx = crypto_skcipher_ctx(tfm); - - kfifo_free(&ctx->queue->softqueue); - sec_alg_skcipher_exit(tfm); -} - -static struct skcipher_alg sec_algs[] = { - { - .base = { - .cra_name = "ecb(aes)", - .cra_driver_name = "hisi_sec_aes_ecb", - .cra_priority = 4001, - .cra_flags = CRYPTO_ALG_ASYNC | - CRYPTO_ALG_ALLOCATES_MEMORY, - .cra_blocksize = AES_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct sec_alg_tfm_ctx), - .cra_alignmask = 0, - .cra_module = THIS_MODULE, - }, - .init = sec_alg_skcipher_init, - .exit = sec_alg_skcipher_exit, - .setkey = sec_alg_skcipher_setkey_aes_ecb, - .decrypt = sec_alg_skcipher_decrypt, - .encrypt = sec_alg_skcipher_encrypt, - .min_keysize = AES_MIN_KEY_SIZE, - .max_keysize = AES_MAX_KEY_SIZE, - .ivsize = 0, - }, { - .base = { - .cra_name = "cbc(aes)", - .cra_driver_name = "hisi_sec_aes_cbc", - .cra_priority = 4001, - .cra_flags = CRYPTO_ALG_ASYNC | - CRYPTO_ALG_ALLOCATES_MEMORY, - .cra_blocksize = AES_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct sec_alg_tfm_ctx), - .cra_alignmask = 0, - .cra_module = THIS_MODULE, - }, - .init = sec_alg_skcipher_init_with_queue, - .exit = sec_alg_skcipher_exit_with_queue, - .setkey = sec_alg_skcipher_setkey_aes_cbc, - .decrypt = sec_alg_skcipher_decrypt, - .encrypt = sec_alg_skcipher_encrypt, - .min_keysize = AES_MIN_KEY_SIZE, - .max_keysize = AES_MAX_KEY_SIZE, - .ivsize = AES_BLOCK_SIZE, - }, { - .base = { - .cra_name = "ctr(aes)", - .cra_driver_name = "hisi_sec_aes_ctr", - .cra_priority = 4001, - .cra_flags = CRYPTO_ALG_ASYNC | - CRYPTO_ALG_ALLOCATES_MEMORY, - .cra_blocksize = AES_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct sec_alg_tfm_ctx), - .cra_alignmask = 0, - .cra_module = THIS_MODULE, - }, - .init = sec_alg_skcipher_init_with_queue, - .exit = sec_alg_skcipher_exit_with_queue, - .setkey = sec_alg_skcipher_setkey_aes_ctr, - .decrypt = sec_alg_skcipher_decrypt, - .encrypt = sec_alg_skcipher_encrypt, - .min_keysize = AES_MIN_KEY_SIZE, - .max_keysize = AES_MAX_KEY_SIZE, - .ivsize = AES_BLOCK_SIZE, - }, { - .base = { - .cra_name = "xts(aes)", - .cra_driver_name = "hisi_sec_aes_xts", - .cra_priority = 4001, - .cra_flags = CRYPTO_ALG_ASYNC | - CRYPTO_ALG_ALLOCATES_MEMORY, - .cra_blocksize = AES_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct sec_alg_tfm_ctx), - .cra_alignmask = 0, - .cra_module = THIS_MODULE, - }, - .init = sec_alg_skcipher_init, - .exit = sec_alg_skcipher_exit, - .setkey = sec_alg_skcipher_setkey_aes_xts, - .decrypt = sec_alg_skcipher_decrypt, - .encrypt = sec_alg_skcipher_encrypt, - .min_keysize = 2 * AES_MIN_KEY_SIZE, - .max_keysize = 2 * AES_MAX_KEY_SIZE, - .ivsize = AES_BLOCK_SIZE, - }, { - /* Unable to find any test vectors so untested */ - .base = { - .cra_name = "ecb(des)", - .cra_driver_name = "hisi_sec_des_ecb", - .cra_priority = 4001, - .cra_flags = CRYPTO_ALG_ASYNC | - CRYPTO_ALG_ALLOCATES_MEMORY, - .cra_blocksize = DES_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct sec_alg_tfm_ctx), - .cra_alignmask = 0, - .cra_module = THIS_MODULE, - }, - .init = sec_alg_skcipher_init, - .exit = sec_alg_skcipher_exit, - .setkey = sec_alg_skcipher_setkey_des_ecb, - .decrypt = sec_alg_skcipher_decrypt, - .encrypt = sec_alg_skcipher_encrypt, - .min_keysize = DES_KEY_SIZE, - .max_keysize = DES_KEY_SIZE, - .ivsize = 0, - }, { - .base = { - .cra_name = "cbc(des)", - .cra_driver_name = "hisi_sec_des_cbc", - .cra_priority = 4001, - .cra_flags = CRYPTO_ALG_ASYNC | - CRYPTO_ALG_ALLOCATES_MEMORY, - .cra_blocksize = DES_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct sec_alg_tfm_ctx), - .cra_alignmask = 0, - .cra_module = THIS_MODULE, - }, - .init = sec_alg_skcipher_init_with_queue, - .exit = sec_alg_skcipher_exit_with_queue, - .setkey = sec_alg_skcipher_setkey_des_cbc, - .decrypt = sec_alg_skcipher_decrypt, - .encrypt = sec_alg_skcipher_encrypt, - .min_keysize = DES_KEY_SIZE, - .max_keysize = DES_KEY_SIZE, - .ivsize = DES_BLOCK_SIZE, - }, { - .base = { - .cra_name = "cbc(des3_ede)", - .cra_driver_name = "hisi_sec_3des_cbc", - .cra_priority = 4001, - .cra_flags = CRYPTO_ALG_ASYNC | - CRYPTO_ALG_ALLOCATES_MEMORY, - .cra_blocksize = DES3_EDE_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct sec_alg_tfm_ctx), - .cra_alignmask = 0, - .cra_module = THIS_MODULE, - }, - .init = sec_alg_skcipher_init_with_queue, - .exit = sec_alg_skcipher_exit_with_queue, - .setkey = sec_alg_skcipher_setkey_3des_cbc, - .decrypt = sec_alg_skcipher_decrypt, - .encrypt = sec_alg_skcipher_encrypt, - .min_keysize = DES3_EDE_KEY_SIZE, - .max_keysize = DES3_EDE_KEY_SIZE, - .ivsize = DES3_EDE_BLOCK_SIZE, - }, { - .base = { - .cra_name = "ecb(des3_ede)", - .cra_driver_name = "hisi_sec_3des_ecb", - .cra_priority = 4001, - .cra_flags = CRYPTO_ALG_ASYNC | - CRYPTO_ALG_ALLOCATES_MEMORY, - .cra_blocksize = DES3_EDE_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct sec_alg_tfm_ctx), - .cra_alignmask = 0, - .cra_module = THIS_MODULE, - }, - .init = sec_alg_skcipher_init, - .exit = sec_alg_skcipher_exit, - .setkey = sec_alg_skcipher_setkey_3des_ecb, - .decrypt = sec_alg_skcipher_decrypt, - .encrypt = sec_alg_skcipher_encrypt, - .min_keysize = DES3_EDE_KEY_SIZE, - .max_keysize = DES3_EDE_KEY_SIZE, - .ivsize = 0, - } -}; - -int sec_algs_register(void) -{ - int ret = 0; - - mutex_lock(&algs_lock); - if (++active_devs != 1) - goto unlock; - - ret = crypto_register_skciphers(sec_algs, ARRAY_SIZE(sec_algs)); - if (ret) - --active_devs; -unlock: - mutex_unlock(&algs_lock); - - return ret; -} - -void sec_algs_unregister(void) -{ - mutex_lock(&algs_lock); - if (--active_devs != 0) - goto unlock; - crypto_unregister_skciphers(sec_algs, ARRAY_SIZE(sec_algs)); - -unlock: - mutex_unlock(&algs_lock); -} diff --git a/drivers/crypto/hisilicon/sec/sec_drv.c b/drivers/crypto/hisilicon/sec/sec_drv.c deleted file mode 100644 index 2514a5e1f9b4..000000000000 --- a/drivers/crypto/hisilicon/sec/sec_drv.c +++ /dev/null @@ -1,1307 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Driver for the HiSilicon SEC units found on Hip06 Hip07 - * - * Copyright (c) 2016-2017 HiSilicon Limited. - */ -#include <linux/acpi.h> -#include <linux/atomic.h> -#include <linux/delay.h> -#include <linux/dma-direction.h> -#include <linux/dma-mapping.h> -#include <linux/dmapool.h> -#include <linux/io.h> -#include <linux/iommu.h> -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/irqreturn.h> -#include <linux/mm.h> -#include <linux/module.h> -#include <linux/of.h> -#include <linux/platform_device.h> -#include <linux/slab.h> - -#include "sec_drv.h" - -#define SEC_QUEUE_AR_FROCE_ALLOC 0 -#define SEC_QUEUE_AR_FROCE_NOALLOC 1 -#define SEC_QUEUE_AR_FROCE_DIS 2 - -#define SEC_QUEUE_AW_FROCE_ALLOC 0 -#define SEC_QUEUE_AW_FROCE_NOALLOC 1 -#define SEC_QUEUE_AW_FROCE_DIS 2 - -/* SEC_ALGSUB registers */ -#define SEC_ALGSUB_CLK_EN_REG 0x03b8 -#define SEC_ALGSUB_CLK_DIS_REG 0x03bc -#define SEC_ALGSUB_CLK_ST_REG 0x535c -#define SEC_ALGSUB_RST_REQ_REG 0x0aa8 -#define SEC_ALGSUB_RST_DREQ_REG 0x0aac -#define SEC_ALGSUB_RST_ST_REG 0x5a54 -#define SEC_ALGSUB_RST_ST_IS_RST BIT(0) - -#define SEC_ALGSUB_BUILD_RST_REQ_REG 0x0ab8 -#define SEC_ALGSUB_BUILD_RST_DREQ_REG 0x0abc -#define SEC_ALGSUB_BUILD_RST_ST_REG 0x5a5c -#define SEC_ALGSUB_BUILD_RST_ST_IS_RST BIT(0) - -#define SEC_SAA_BASE 0x00001000UL - -/* SEC_SAA registers */ -#define SEC_SAA_CTRL_REG(x) ((x) * SEC_SAA_ADDR_SIZE) -#define SEC_SAA_CTRL_GET_QM_EN BIT(0) - -#define SEC_ST_INTMSK1_REG 0x0200 -#define SEC_ST_RINT1_REG 0x0400 -#define SEC_ST_INTSTS1_REG 0x0600 -#define SEC_BD_MNG_STAT_REG 0x0800 -#define SEC_PARSING_STAT_REG 0x0804 -#define SEC_LOAD_TIME_OUT_CNT_REG 0x0808 -#define SEC_CORE_WORK_TIME_OUT_CNT_REG 0x080c -#define SEC_BACK_TIME_OUT_CNT_REG 0x0810 -#define SEC_BD1_PARSING_RD_TIME_OUT_CNT_REG 0x0814 -#define SEC_BD1_PARSING_WR_TIME_OUT_CNT_REG 0x0818 -#define SEC_BD2_PARSING_RD_TIME_OUT_CNT_REG 0x081c -#define SEC_BD2_PARSING_WR_TIME_OUT_CNT_REG 0x0820 -#define SEC_SAA_ACC_REG 0x083c -#define SEC_BD_NUM_CNT_IN_SEC_REG 0x0858 -#define SEC_LOAD_WORK_TIME_CNT_REG 0x0860 -#define SEC_CORE_WORK_WORK_TIME_CNT_REG 0x0864 -#define SEC_BACK_WORK_TIME_CNT_REG 0x0868 -#define SEC_SAA_IDLE_TIME_CNT_REG 0x086c -#define SEC_SAA_CLK_CNT_REG 0x0870 - -/* SEC_COMMON registers */ -#define SEC_CLK_EN_REG 0x0000 -#define SEC_CTRL_REG 0x0004 - -#define SEC_COMMON_CNT_CLR_CE_REG 0x0008 -#define SEC_COMMON_CNT_CLR_CE_CLEAR BIT(0) -#define SEC_COMMON_CNT_CLR_CE_SNAP_EN BIT(1) - -#define SEC_SECURE_CTRL_REG 0x000c -#define SEC_AXI_CACHE_CFG_REG 0x0010 -#define SEC_AXI_QOS_CFG_REG 0x0014 -#define SEC_IPV4_MASK_TABLE_REG 0x0020 -#define SEC_IPV6_MASK_TABLE_X_REG(x) (0x0024 + (x) * 4) -#define SEC_FSM_MAX_CNT_REG 0x0064 - -#define SEC_CTRL2_REG 0x0068 -#define SEC_CTRL2_DATA_AXI_RD_OTSD_CFG_M GENMASK(3, 0) -#define SEC_CTRL2_DATA_AXI_RD_OTSD_CFG_S 0 -#define SEC_CTRL2_DATA_AXI_WR_OTSD_CFG_M GENMASK(6, 4) -#define SEC_CTRL2_DATA_AXI_WR_OTSD_CFG_S 4 -#define SEC_CTRL2_CLK_GATE_EN BIT(7) -#define SEC_CTRL2_ENDIAN_BD BIT(8) -#define SEC_CTRL2_ENDIAN_BD_TYPE BIT(9) - -#define SEC_CNT_PRECISION_CFG_REG 0x006c -#define SEC_DEBUG_BD_CFG_REG 0x0070 -#define SEC_DEBUG_BD_CFG_WB_NORMAL BIT(0) -#define SEC_DEBUG_BD_CFG_WB_EN BIT(1) - -#define SEC_Q_SIGHT_SEL 0x0074 -#define SEC_Q_SIGHT_HIS_CLR 0x0078 -#define SEC_Q_VMID_CFG_REG(q) (0x0100 + (q) * 4) -#define SEC_Q_WEIGHT_CFG_REG(q) (0x200 + (q) * 4) -#define SEC_STAT_CLR_REG 0x0a00 -#define SEC_SAA_IDLE_CNT_CLR_REG 0x0a04 -#define SEC_QM_CPL_Q_IDBUF_DFX_CFG_REG 0x0b00 -#define SEC_QM_CPL_Q_IDBUF_DFX_RESULT_REG 0x0b04 -#define SEC_QM_BD_DFX_CFG_REG 0x0b08 -#define SEC_QM_BD_DFX_RESULT_REG 0x0b0c -#define SEC_QM_BDID_DFX_RESULT_REG 0x0b10 -#define SEC_QM_BD_DFIFO_STATUS_REG 0x0b14 -#define SEC_QM_BD_DFX_CFG2_REG 0x0b1c -#define SEC_QM_BD_DFX_RESULT2_REG 0x0b20 -#define SEC_QM_BD_IDFIFO_STATUS_REG 0x0b18 -#define SEC_QM_BD_DFIFO_STATUS2_REG 0x0b28 -#define SEC_QM_BD_IDFIFO_STATUS2_REG 0x0b2c - -#define SEC_HASH_IPV4_MASK 0xfff00000 -#define SEC_MAX_SAA_NUM 0xa -#define SEC_SAA_ADDR_SIZE 0x1000 - -#define SEC_Q_INIT_REG 0x0 -#define SEC_Q_INIT_WO_STAT_CLEAR 0x2 -#define SEC_Q_INIT_AND_STAT_CLEAR 0x3 - -#define SEC_Q_CFG_REG 0x8 -#define SEC_Q_CFG_REORDER BIT(0) - -#define SEC_Q_PROC_NUM_CFG_REG 0x10 -#define SEC_QUEUE_ENB_REG 0x18 - -#define SEC_Q_DEPTH_CFG_REG 0x50 -#define SEC_Q_DEPTH_CFG_DEPTH_M GENMASK(11, 0) -#define SEC_Q_DEPTH_CFG_DEPTH_S 0 - -#define SEC_Q_BASE_HADDR_REG 0x54 -#define SEC_Q_BASE_LADDR_REG 0x58 -#define SEC_Q_WR_PTR_REG 0x5c -#define SEC_Q_OUTORDER_BASE_HADDR_REG 0x60 -#define SEC_Q_OUTORDER_BASE_LADDR_REG 0x64 -#define SEC_Q_OUTORDER_RD_PTR_REG 0x68 -#define SEC_Q_OT_TH_REG 0x6c - -#define SEC_Q_ARUSER_CFG_REG 0x70 -#define SEC_Q_ARUSER_CFG_FA BIT(0) -#define SEC_Q_ARUSER_CFG_FNA BIT(1) -#define SEC_Q_ARUSER_CFG_RINVLD BIT(2) -#define SEC_Q_ARUSER_CFG_PKG BIT(3) - -#define SEC_Q_AWUSER_CFG_REG 0x74 -#define SEC_Q_AWUSER_CFG_FA BIT(0) -#define SEC_Q_AWUSER_CFG_FNA BIT(1) -#define SEC_Q_AWUSER_CFG_PKG BIT(2) - -#define SEC_Q_ERR_BASE_HADDR_REG 0x7c -#define SEC_Q_ERR_BASE_LADDR_REG 0x80 -#define SEC_Q_CFG_VF_NUM_REG 0x84 -#define SEC_Q_SOFT_PROC_PTR_REG 0x88 -#define SEC_Q_FAIL_INT_MSK_REG 0x300 -#define SEC_Q_FLOW_INT_MKS_REG 0x304 -#define SEC_Q_FAIL_RINT_REG 0x400 -#define SEC_Q_FLOW_RINT_REG 0x404 -#define SEC_Q_FAIL_INT_STATUS_REG 0x500 -#define SEC_Q_FLOW_INT_STATUS_REG 0x504 -#define SEC_Q_STATUS_REG 0x600 -#define SEC_Q_RD_PTR_REG 0x604 -#define SEC_Q_PRO_PTR_REG 0x608 -#define SEC_Q_OUTORDER_WR_PTR_REG 0x60c -#define SEC_Q_OT_CNT_STATUS_REG 0x610 -#define SEC_Q_INORDER_BD_NUM_ST_REG 0x650 -#define SEC_Q_INORDER_GET_FLAG_ST_REG 0x654 -#define SEC_Q_INORDER_ADD_FLAG_ST_REG 0x658 -#define SEC_Q_INORDER_TASK_INT_NUM_LEFT_ST_REG 0x65c -#define SEC_Q_RD_DONE_PTR_REG 0x660 -#define SEC_Q_CPL_Q_BD_NUM_ST_REG 0x700 -#define SEC_Q_CPL_Q_PTR_ST_REG 0x704 -#define SEC_Q_CPL_Q_H_ADDR_ST_REG 0x708 -#define SEC_Q_CPL_Q_L_ADDR_ST_REG 0x70c -#define SEC_Q_CPL_TASK_INT_NUM_LEFT_ST_REG 0x710 -#define SEC_Q_WRR_ID_CHECK_REG 0x714 -#define SEC_Q_CPLQ_FULL_CHECK_REG 0x718 -#define SEC_Q_SUCCESS_BD_CNT_REG 0x800 -#define SEC_Q_FAIL_BD_CNT_REG 0x804 -#define SEC_Q_GET_BD_CNT_REG 0x808 -#define SEC_Q_IVLD_CNT_REG 0x80c -#define SEC_Q_BD_PROC_GET_CNT_REG 0x810 -#define SEC_Q_BD_PROC_DONE_CNT_REG 0x814 -#define SEC_Q_LAT_CLR_REG 0x850 -#define SEC_Q_PKT_LAT_MAX_REG 0x854 -#define SEC_Q_PKT_LAT_AVG_REG 0x858 -#define SEC_Q_PKT_LAT_MIN_REG 0x85c -#define SEC_Q_ID_CLR_CFG_REG 0x900 -#define SEC_Q_1ST_BD_ERR_ID_REG 0x904 -#define SEC_Q_1ST_AUTH_FAIL_ID_REG 0x908 -#define SEC_Q_1ST_RD_ERR_ID_REG 0x90c -#define SEC_Q_1ST_ECC2_ERR_ID_REG 0x910 -#define SEC_Q_1ST_IVLD_ID_REG 0x914 -#define SEC_Q_1ST_BD_WR_ERR_ID_REG 0x918 -#define SEC_Q_1ST_ERR_BD_WR_ERR_ID_REG 0x91c -#define SEC_Q_1ST_BD_MAC_WR_ERR_ID_REG 0x920 - -struct sec_debug_bd_info { -#define SEC_DEBUG_BD_INFO_SOFT_ERR_CHECK_M GENMASK(22, 0) - u32 soft_err_check; -#define SEC_DEBUG_BD_INFO_HARD_ERR_CHECK_M GENMASK(9, 0) - u32 hard_err_check; - u32 icv_mac1st_word; -#define SEC_DEBUG_BD_INFO_GET_ID_M GENMASK(19, 0) - u32 sec_get_id; - /* W4---W15 */ - u32 reserv_left[12]; -}; - -struct sec_out_bd_info { -#define SEC_OUT_BD_INFO_Q_ID_M GENMASK(11, 0) -#define SEC_OUT_BD_INFO_ECC_2BIT_ERR BIT(14) - u16 data; -}; - -#define SEC_MAX_DEVICES 8 -static struct sec_dev_info *sec_devices[SEC_MAX_DEVICES]; -static DEFINE_MUTEX(sec_id_lock); - -static int sec_queue_map_io(struct sec_queue *queue) -{ - struct device *dev = queue->dev_info->dev; - struct resource *res; - - res = platform_get_resource(to_platform_device(dev), - IORESOURCE_MEM, - 2 + queue->queue_id); - if (!res) { - dev_err(dev, "Failed to get queue %u memory resource\n", - queue->queue_id); - return -ENOMEM; - } - queue->regs = ioremap(res->start, resource_size(res)); - if (!queue->regs) - return -ENOMEM; - - return 0; -} - -static void sec_queue_unmap_io(struct sec_queue *queue) -{ - iounmap(queue->regs); -} - -static int sec_queue_ar_pkgattr(struct sec_queue *queue, u32 ar_pkg) -{ - void __iomem *addr = queue->regs + SEC_Q_ARUSER_CFG_REG; - u32 regval; - - regval = readl_relaxed(addr); - if (ar_pkg) - regval |= SEC_Q_ARUSER_CFG_PKG; - else - regval &= ~SEC_Q_ARUSER_CFG_PKG; - writel_relaxed(regval, addr); - - return 0; -} - -static int sec_queue_aw_pkgattr(struct sec_queue *queue, u32 aw_pkg) -{ - void __iomem *addr = queue->regs + SEC_Q_AWUSER_CFG_REG; - u32 regval; - - regval = readl_relaxed(addr); - regval |= SEC_Q_AWUSER_CFG_PKG; - writel_relaxed(regval, addr); - - return 0; -} - -static int sec_clk_en(struct sec_dev_info *info) -{ - void __iomem *base = info->regs[SEC_COMMON]; - u32 i = 0; - - writel_relaxed(0x7, base + SEC_ALGSUB_CLK_EN_REG); - do { - usleep_range(1000, 10000); - if ((readl_relaxed(base + SEC_ALGSUB_CLK_ST_REG) & 0x7) == 0x7) - return 0; - i++; - } while (i < 10); - dev_err(info->dev, "sec clock enable fail!\n"); - - return -EIO; -} - -static int sec_clk_dis(struct sec_dev_info *info) -{ - void __iomem *base = info->regs[SEC_COMMON]; - u32 i = 0; - - writel_relaxed(0x7, base + SEC_ALGSUB_CLK_DIS_REG); - do { - usleep_range(1000, 10000); - if ((readl_relaxed(base + SEC_ALGSUB_CLK_ST_REG) & 0x7) == 0) - return 0; - i++; - } while (i < 10); - dev_err(info->dev, "sec clock disable fail!\n"); - - return -EIO; -} - -static int sec_reset_whole_module(struct sec_dev_info *info) -{ - void __iomem *base = info->regs[SEC_COMMON]; - bool is_reset, b_is_reset; - u32 i = 0; - - writel_relaxed(1, base + SEC_ALGSUB_RST_REQ_REG); - writel_relaxed(1, base + SEC_ALGSUB_BUILD_RST_REQ_REG); - while (1) { - usleep_range(1000, 10000); - is_reset = readl_relaxed(base + SEC_ALGSUB_RST_ST_REG) & - SEC_ALGSUB_RST_ST_IS_RST; - b_is_reset = readl_relaxed(base + SEC_ALGSUB_BUILD_RST_ST_REG) & - SEC_ALGSUB_BUILD_RST_ST_IS_RST; - if (is_reset && b_is_reset) - break; - i++; - if (i > 10) { - dev_err(info->dev, "Reset req failed\n"); - return -EIO; - } - } - - i = 0; - writel_relaxed(1, base + SEC_ALGSUB_RST_DREQ_REG); - writel_relaxed(1, base + SEC_ALGSUB_BUILD_RST_DREQ_REG); - while (1) { - usleep_range(1000, 10000); - is_reset = readl_relaxed(base + SEC_ALGSUB_RST_ST_REG) & - SEC_ALGSUB_RST_ST_IS_RST; - b_is_reset = readl_relaxed(base + SEC_ALGSUB_BUILD_RST_ST_REG) & - SEC_ALGSUB_BUILD_RST_ST_IS_RST; - if (!is_reset && !b_is_reset) - break; - - i++; - if (i > 10) { - dev_err(info->dev, "Reset dreq failed\n"); - return -EIO; - } - } - - return 0; -} - -static void sec_bd_endian_little(struct sec_dev_info *info) -{ - void __iomem *addr = info->regs[SEC_SAA] + SEC_CTRL2_REG; - u32 regval; - - regval = readl_relaxed(addr); - regval &= ~(SEC_CTRL2_ENDIAN_BD | SEC_CTRL2_ENDIAN_BD_TYPE); - writel_relaxed(regval, addr); -} - -/* - * sec_cache_config - configure optimum cache placement - */ -static void sec_cache_config(struct sec_dev_info *info) -{ - struct iommu_domain *domain; - void __iomem *addr = info->regs[SEC_SAA] + SEC_CTRL_REG; - - domain = iommu_get_domain_for_dev(info->dev); - - /* Check that translation is occurring */ - if (domain && (domain->type & __IOMMU_DOMAIN_PAGING)) - writel_relaxed(0x44cf9e, addr); - else - writel_relaxed(0x4cfd9, addr); -} - -static void sec_data_axiwr_otsd_cfg(struct sec_dev_info *info, u32 cfg) -{ - void __iomem *addr = info->regs[SEC_SAA] + SEC_CTRL2_REG; - u32 regval; - - regval = readl_relaxed(addr); - regval &= ~SEC_CTRL2_DATA_AXI_WR_OTSD_CFG_M; - regval |= (cfg << SEC_CTRL2_DATA_AXI_WR_OTSD_CFG_S) & - SEC_CTRL2_DATA_AXI_WR_OTSD_CFG_M; - writel_relaxed(regval, addr); -} - -static void sec_data_axird_otsd_cfg(struct sec_dev_info *info, u32 cfg) -{ - void __iomem *addr = info->regs[SEC_SAA] + SEC_CTRL2_REG; - u32 regval; - - regval = readl_relaxed(addr); - regval &= ~SEC_CTRL2_DATA_AXI_RD_OTSD_CFG_M; - regval |= (cfg << SEC_CTRL2_DATA_AXI_RD_OTSD_CFG_S) & - SEC_CTRL2_DATA_AXI_RD_OTSD_CFG_M; - writel_relaxed(regval, addr); -} - -static void sec_clk_gate_en(struct sec_dev_info *info, bool clkgate) -{ - void __iomem *addr = info->regs[SEC_SAA] + SEC_CTRL2_REG; - u32 regval; - - regval = readl_relaxed(addr); - if (clkgate) - regval |= SEC_CTRL2_CLK_GATE_EN; - else - regval &= ~SEC_CTRL2_CLK_GATE_EN; - writel_relaxed(regval, addr); -} - -static void sec_comm_cnt_cfg(struct sec_dev_info *info, bool clr_ce) -{ - void __iomem *addr = info->regs[SEC_SAA] + SEC_COMMON_CNT_CLR_CE_REG; - u32 regval; - - regval = readl_relaxed(addr); - if (clr_ce) - regval |= SEC_COMMON_CNT_CLR_CE_CLEAR; - else - regval &= ~SEC_COMMON_CNT_CLR_CE_CLEAR; - writel_relaxed(regval, addr); -} - -static void sec_commsnap_en(struct sec_dev_info *info, bool snap_en) -{ - void __iomem *addr = info->regs[SEC_SAA] + SEC_COMMON_CNT_CLR_CE_REG; - u32 regval; - - regval = readl_relaxed(addr); - if (snap_en) - regval |= SEC_COMMON_CNT_CLR_CE_SNAP_EN; - else - regval &= ~SEC_COMMON_CNT_CLR_CE_SNAP_EN; - writel_relaxed(regval, addr); -} - -static void sec_ipv6_hashmask(struct sec_dev_info *info, u32 hash_mask[]) -{ - void __iomem *base = info->regs[SEC_SAA]; - int i; - - for (i = 0; i < 10; i++) - writel_relaxed(hash_mask[0], - base + SEC_IPV6_MASK_TABLE_X_REG(i)); -} - -static int sec_ipv4_hashmask(struct sec_dev_info *info, u32 hash_mask) -{ - if (hash_mask & SEC_HASH_IPV4_MASK) { - dev_err(info->dev, "Sec Ipv4 Hash Mask Input Error!\n"); - return -EINVAL; - } - - writel_relaxed(hash_mask, - info->regs[SEC_SAA] + SEC_IPV4_MASK_TABLE_REG); - - return 0; -} - -static void sec_set_dbg_bd_cfg(struct sec_dev_info *info, u32 cfg) -{ - void __iomem *addr = info->regs[SEC_SAA] + SEC_DEBUG_BD_CFG_REG; - u32 regval; - - regval = readl_relaxed(addr); - /* Always disable write back of normal bd */ - regval &= ~SEC_DEBUG_BD_CFG_WB_NORMAL; - - if (cfg) - regval &= ~SEC_DEBUG_BD_CFG_WB_EN; - else - regval |= SEC_DEBUG_BD_CFG_WB_EN; - - writel_relaxed(regval, addr); -} - -static void sec_saa_getqm_en(struct sec_dev_info *info, u32 saa_indx, u32 en) -{ - void __iomem *addr = info->regs[SEC_SAA] + SEC_SAA_BASE + - SEC_SAA_CTRL_REG(saa_indx); - u32 regval; - - regval = readl_relaxed(addr); - if (en) - regval |= SEC_SAA_CTRL_GET_QM_EN; - else - regval &= ~SEC_SAA_CTRL_GET_QM_EN; - writel_relaxed(regval, addr); -} - -static void sec_saa_int_mask(struct sec_dev_info *info, u32 saa_indx, - u32 saa_int_mask) -{ - writel_relaxed(saa_int_mask, - info->regs[SEC_SAA] + SEC_SAA_BASE + SEC_ST_INTMSK1_REG + - saa_indx * SEC_SAA_ADDR_SIZE); -} - -static void sec_streamid(struct sec_dev_info *info, int i) -{ - #define SEC_SID 0x600 - #define SEC_VMID 0 - - writel_relaxed((SEC_VMID | ((SEC_SID & 0xffff) << 8)), - info->regs[SEC_SAA] + SEC_Q_VMID_CFG_REG(i)); -} - -static void sec_queue_ar_alloc(struct sec_queue *queue, u32 alloc) -{ - void __iomem *addr = queue->regs + SEC_Q_ARUSER_CFG_REG; - u32 regval; - - regval = readl_relaxed(addr); - if (alloc == SEC_QUEUE_AR_FROCE_ALLOC) { - regval |= SEC_Q_ARUSER_CFG_FA; - regval &= ~SEC_Q_ARUSER_CFG_FNA; - } else { - regval &= ~SEC_Q_ARUSER_CFG_FA; - regval |= SEC_Q_ARUSER_CFG_FNA; - } - - writel_relaxed(regval, addr); -} - -static void sec_queue_aw_alloc(struct sec_queue *queue, u32 alloc) -{ - void __iomem *addr = queue->regs + SEC_Q_AWUSER_CFG_REG; - u32 regval; - - regval = readl_relaxed(addr); - if (alloc == SEC_QUEUE_AW_FROCE_ALLOC) { - regval |= SEC_Q_AWUSER_CFG_FA; - regval &= ~SEC_Q_AWUSER_CFG_FNA; - } else { - regval &= ~SEC_Q_AWUSER_CFG_FA; - regval |= SEC_Q_AWUSER_CFG_FNA; - } - - writel_relaxed(regval, addr); -} - -static void sec_queue_reorder(struct sec_queue *queue, bool reorder) -{ - void __iomem *base = queue->regs; - u32 regval; - - regval = readl_relaxed(base + SEC_Q_CFG_REG); - if (reorder) - regval |= SEC_Q_CFG_REORDER; - else - regval &= ~SEC_Q_CFG_REORDER; - writel_relaxed(regval, base + SEC_Q_CFG_REG); -} - -static void sec_queue_depth(struct sec_queue *queue, u32 depth) -{ - void __iomem *addr = queue->regs + SEC_Q_DEPTH_CFG_REG; - u32 regval; - - regval = readl_relaxed(addr); - regval &= ~SEC_Q_DEPTH_CFG_DEPTH_M; - regval |= (depth << SEC_Q_DEPTH_CFG_DEPTH_S) & SEC_Q_DEPTH_CFG_DEPTH_M; - - writel_relaxed(regval, addr); -} - -static void sec_queue_cmdbase_addr(struct sec_queue *queue, u64 addr) -{ - writel_relaxed(upper_32_bits(addr), queue->regs + SEC_Q_BASE_HADDR_REG); - writel_relaxed(lower_32_bits(addr), queue->regs + SEC_Q_BASE_LADDR_REG); -} - -static void sec_queue_outorder_addr(struct sec_queue *queue, u64 addr) -{ - writel_relaxed(upper_32_bits(addr), - queue->regs + SEC_Q_OUTORDER_BASE_HADDR_REG); - writel_relaxed(lower_32_bits(addr), - queue->regs + SEC_Q_OUTORDER_BASE_LADDR_REG); -} - -static void sec_queue_errbase_addr(struct sec_queue *queue, u64 addr) -{ - writel_relaxed(upper_32_bits(addr), - queue->regs + SEC_Q_ERR_BASE_HADDR_REG); - writel_relaxed(lower_32_bits(addr), - queue->regs + SEC_Q_ERR_BASE_LADDR_REG); -} - -static void sec_queue_irq_disable(struct sec_queue *queue) -{ - writel_relaxed((u32)~0, queue->regs + SEC_Q_FLOW_INT_MKS_REG); -} - -static void sec_queue_irq_enable(struct sec_queue *queue) -{ - writel_relaxed(0, queue->regs + SEC_Q_FLOW_INT_MKS_REG); -} - -static void sec_queue_abn_irq_disable(struct sec_queue *queue) -{ - writel_relaxed((u32)~0, queue->regs + SEC_Q_FAIL_INT_MSK_REG); -} - -static void sec_queue_stop(struct sec_queue *queue) -{ - disable_irq(queue->task_irq); - sec_queue_irq_disable(queue); - writel_relaxed(0x0, queue->regs + SEC_QUEUE_ENB_REG); -} - -static void sec_queue_start(struct sec_queue *queue) -{ - sec_queue_irq_enable(queue); - enable_irq(queue->task_irq); - queue->expected = 0; - writel_relaxed(SEC_Q_INIT_AND_STAT_CLEAR, queue->regs + SEC_Q_INIT_REG); - writel_relaxed(0x1, queue->regs + SEC_QUEUE_ENB_REG); -} - -static struct sec_queue *sec_alloc_queue(struct sec_dev_info *info) -{ - int i; - - mutex_lock(&info->dev_lock); - - /* Get the first idle queue in SEC device */ - for (i = 0; i < SEC_Q_NUM; i++) - if (!info->queues[i].in_use) { - info->queues[i].in_use = true; - info->queues_in_use++; - mutex_unlock(&info->dev_lock); - - return &info->queues[i]; - } - mutex_unlock(&info->dev_lock); - - return ERR_PTR(-ENODEV); -} - -static int sec_queue_free(struct sec_queue *queue) -{ - struct sec_dev_info *info = queue->dev_info; - - if (queue->queue_id >= SEC_Q_NUM) { - dev_err(info->dev, "No queue %u\n", queue->queue_id); - return -ENODEV; - } - - if (!queue->in_use) { - dev_err(info->dev, "Queue %u is idle\n", queue->queue_id); - return -ENODEV; - } - - mutex_lock(&info->dev_lock); - queue->in_use = false; - info->queues_in_use--; - mutex_unlock(&info->dev_lock); - - return 0; -} - -static irqreturn_t sec_isr_handle_th(int irq, void *q) -{ - sec_queue_irq_disable(q); - return IRQ_WAKE_THREAD; -} - -static irqreturn_t sec_isr_handle(int irq, void *q) -{ - struct sec_queue *queue = q; - struct sec_queue_ring_cmd *msg_ring = &queue->ring_cmd; - struct sec_queue_ring_cq *cq_ring = &queue->ring_cq; - struct sec_out_bd_info *outorder_msg; - struct sec_bd_info *msg; - u32 ooo_read, ooo_write; - void __iomem *base = queue->regs; - int q_id; - - ooo_read = readl(base + SEC_Q_OUTORDER_RD_PTR_REG); - ooo_write = readl(base + SEC_Q_OUTORDER_WR_PTR_REG); - outorder_msg = cq_ring->vaddr + ooo_read; - q_id = outorder_msg->data & SEC_OUT_BD_INFO_Q_ID_M; - msg = msg_ring->vaddr + q_id; - - while ((ooo_write != ooo_read) && msg->w0 & SEC_BD_W0_DONE) { - /* - * Must be before callback otherwise blocks adding other chained - * elements - */ - set_bit(q_id, queue->unprocessed); - if (q_id == queue->expected) - while (test_bit(queue->expected, queue->unprocessed)) { - clear_bit(queue->expected, queue->unprocessed); - msg = msg_ring->vaddr + queue->expected; - msg->w0 &= ~SEC_BD_W0_DONE; - msg_ring->callback(msg, - queue->shadow[queue->expected]); - queue->shadow[queue->expected] = NULL; - queue->expected = (queue->expected + 1) % - SEC_QUEUE_LEN; - atomic_dec(&msg_ring->used); - } - - ooo_read = (ooo_read + 1) % SEC_QUEUE_LEN; - writel(ooo_read, base + SEC_Q_OUTORDER_RD_PTR_REG); - ooo_write = readl(base + SEC_Q_OUTORDER_WR_PTR_REG); - outorder_msg = cq_ring->vaddr + ooo_read; - q_id = outorder_msg->data & SEC_OUT_BD_INFO_Q_ID_M; - msg = msg_ring->vaddr + q_id; - } - - sec_queue_irq_enable(queue); - - return IRQ_HANDLED; -} - -static int sec_queue_irq_init(struct sec_queue *queue) -{ - struct sec_dev_info *info = queue->dev_info; - int irq = queue->task_irq; - int ret; - - ret = request_threaded_irq(irq, sec_isr_handle_th, sec_isr_handle, - IRQF_TRIGGER_RISING, queue->name, queue); - if (ret) { - dev_err(info->dev, "request irq(%d) failed %d\n", irq, ret); - return ret; - } - disable_irq(irq); - - return 0; -} - -static int sec_queue_irq_uninit(struct sec_queue *queue) -{ - free_irq(queue->task_irq, queue); - - return 0; -} - -static struct sec_dev_info *sec_device_get(void) -{ - struct sec_dev_info *sec_dev = NULL; - struct sec_dev_info *this_sec_dev; - int least_busy_n = SEC_Q_NUM + 1; - int i; - - /* Find which one is least busy and use that first */ - for (i = 0; i < SEC_MAX_DEVICES; i++) { - this_sec_dev = sec_devices[i]; - if (this_sec_dev && - this_sec_dev->queues_in_use < least_busy_n) { - least_busy_n = this_sec_dev->queues_in_use; - sec_dev = this_sec_dev; - } - } - - return sec_dev; -} - -static struct sec_queue *sec_queue_alloc_start(struct sec_dev_info *info) -{ - struct sec_queue *queue; - - queue = sec_alloc_queue(info); - if (IS_ERR(queue)) { - dev_err(info->dev, "alloc sec queue failed! %ld\n", - PTR_ERR(queue)); - return queue; - } - - sec_queue_start(queue); - - return queue; -} - -/** - * sec_queue_alloc_start_safe - get a hw queue from appropriate instance - * - * This function does extremely simplistic load balancing. It does not take into - * account NUMA locality of the accelerator, or which cpu has requested the - * queue. Future work may focus on optimizing this in order to improve full - * machine throughput. - */ -struct sec_queue *sec_queue_alloc_start_safe(void) -{ - struct sec_dev_info *info; - struct sec_queue *queue = ERR_PTR(-ENODEV); - - mutex_lock(&sec_id_lock); - info = sec_device_get(); - if (!info) - goto unlock; - - queue = sec_queue_alloc_start(info); - -unlock: - mutex_unlock(&sec_id_lock); - - return queue; -} - -/** - * sec_queue_stop_release() - free up a hw queue for reuse - * @queue: The queue we are done with. - * - * This will stop the current queue, terminanting any transactions - * that are inflight an return it to the pool of available hw queuess - */ -int sec_queue_stop_release(struct sec_queue *queue) -{ - struct device *dev = queue->dev_info->dev; - int ret; - - sec_queue_stop(queue); - - ret = sec_queue_free(queue); - if (ret) - dev_err(dev, "Releasing queue failed %d\n", ret); - - return ret; -} - -/** - * sec_queue_empty() - Is this hardware queue currently empty. - * @queue: The queue to test - * - * We need to know if we have an empty queue for some of the chaining modes - * as if it is not empty we may need to hold the message in a software queue - * until the hw queue is drained. - */ -bool sec_queue_empty(struct sec_queue *queue) -{ - struct sec_queue_ring_cmd *msg_ring = &queue->ring_cmd; - - return !atomic_read(&msg_ring->used); -} - -/** - * sec_queue_send() - queue up a single operation in the hw queue - * @queue: The queue in which to put the message - * @msg: The message - * @ctx: Context to be put in the shadow array and passed back to cb on result. - * - * This function will return -EAGAIN if the queue is currently full. - */ -int sec_queue_send(struct sec_queue *queue, struct sec_bd_info *msg, void *ctx) -{ - struct sec_queue_ring_cmd *msg_ring = &queue->ring_cmd; - void __iomem *base = queue->regs; - u32 write, read; - - mutex_lock(&msg_ring->lock); - read = readl(base + SEC_Q_RD_PTR_REG); - write = readl(base + SEC_Q_WR_PTR_REG); - if (write == read && atomic_read(&msg_ring->used) == SEC_QUEUE_LEN) { - mutex_unlock(&msg_ring->lock); - return -EAGAIN; - } - memcpy(msg_ring->vaddr + write, msg, sizeof(*msg)); - queue->shadow[write] = ctx; - write = (write + 1) % SEC_QUEUE_LEN; - - /* Ensure content updated before queue advance */ - wmb(); - writel(write, base + SEC_Q_WR_PTR_REG); - - atomic_inc(&msg_ring->used); - mutex_unlock(&msg_ring->lock); - - return 0; -} - -bool sec_queue_can_enqueue(struct sec_queue *queue, int num) -{ - struct sec_queue_ring_cmd *msg_ring = &queue->ring_cmd; - - return SEC_QUEUE_LEN - atomic_read(&msg_ring->used) >= num; -} - -static void sec_queue_hw_init(struct sec_queue *queue) -{ - sec_queue_ar_alloc(queue, SEC_QUEUE_AR_FROCE_NOALLOC); - sec_queue_aw_alloc(queue, SEC_QUEUE_AW_FROCE_NOALLOC); - sec_queue_ar_pkgattr(queue, 1); - sec_queue_aw_pkgattr(queue, 1); - - /* Enable out of order queue */ - sec_queue_reorder(queue, true); - - /* Interrupt after a single complete element */ - writel_relaxed(1, queue->regs + SEC_Q_PROC_NUM_CFG_REG); - - sec_queue_depth(queue, SEC_QUEUE_LEN - 1); - - sec_queue_cmdbase_addr(queue, queue->ring_cmd.paddr); - - sec_queue_outorder_addr(queue, queue->ring_cq.paddr); - - sec_queue_errbase_addr(queue, queue->ring_db.paddr); - - writel_relaxed(0x100, queue->regs + SEC_Q_OT_TH_REG); - - sec_queue_abn_irq_disable(queue); - sec_queue_irq_disable(queue); - writel_relaxed(SEC_Q_INIT_AND_STAT_CLEAR, queue->regs + SEC_Q_INIT_REG); -} - -static int sec_hw_init(struct sec_dev_info *info) -{ - struct iommu_domain *domain; - u32 sec_ipv4_mask = 0; - u32 sec_ipv6_mask[10] = {}; - int ret; - u32 i; - - domain = iommu_get_domain_for_dev(info->dev); - - /* - * Enable all available processing unit clocks. - * Only the first cluster is usable with translations. - */ - if (domain && (domain->type & __IOMMU_DOMAIN_PAGING)) - info->num_saas = 5; - - else - info->num_saas = 10; - - writel_relaxed(GENMASK(info->num_saas - 1, 0), - info->regs[SEC_SAA] + SEC_CLK_EN_REG); - - /* 32 bit little endian */ - sec_bd_endian_little(info); - - sec_cache_config(info); - - /* Data axi port write and read outstanding config as per datasheet */ - sec_data_axiwr_otsd_cfg(info, 0x7); - sec_data_axird_otsd_cfg(info, 0x7); - - /* Enable clock gating */ - sec_clk_gate_en(info, true); - - /* Set CNT_CYC register not read clear */ - sec_comm_cnt_cfg(info, false); - - /* Enable CNT_CYC */ - sec_commsnap_en(info, false); - - writel_relaxed((u32)~0, info->regs[SEC_SAA] + SEC_FSM_MAX_CNT_REG); - - ret = sec_ipv4_hashmask(info, sec_ipv4_mask); - if (ret) { - dev_err(info->dev, "Failed to set ipv4 hashmask %d\n", ret); - return -EIO; - } - - sec_ipv6_hashmask(info, sec_ipv6_mask); - - /* do not use debug bd */ - sec_set_dbg_bd_cfg(info, 0); - - if (domain && (domain->type & __IOMMU_DOMAIN_PAGING)) { - for (i = 0; i < SEC_Q_NUM; i++) { - sec_streamid(info, i); - /* Same QoS for all queues */ - writel_relaxed(0x3f, - info->regs[SEC_SAA] + - SEC_Q_WEIGHT_CFG_REG(i)); - } - } - - for (i = 0; i < info->num_saas; i++) { - sec_saa_getqm_en(info, i, 1); - sec_saa_int_mask(info, i, 0); - } - - return 0; -} - -static void sec_hw_exit(struct sec_dev_info *info) -{ - int i; - - for (i = 0; i < SEC_MAX_SAA_NUM; i++) { - sec_saa_int_mask(info, i, (u32)~0); - sec_saa_getqm_en(info, i, 0); - } -} - -static void sec_queue_base_init(struct sec_dev_info *info, - struct sec_queue *queue, int queue_id) -{ - queue->dev_info = info; - queue->queue_id = queue_id; - snprintf(queue->name, sizeof(queue->name), - "%s_%d", dev_name(info->dev), queue->queue_id); -} - -static int sec_map_io(struct sec_dev_info *info, struct platform_device *pdev) -{ - int i; - - for (i = 0; i < SEC_NUM_ADDR_REGIONS; i++) { - info->regs[i] = devm_platform_ioremap_resource(pdev, i); - if (IS_ERR(info->regs[i])) - return PTR_ERR(info->regs[i]); - } - - return 0; -} - -static int sec_base_init(struct sec_dev_info *info, - struct platform_device *pdev) -{ - int ret; - - ret = sec_map_io(info, pdev); - if (ret) - return ret; - - ret = sec_clk_en(info); - if (ret) - return ret; - - ret = sec_reset_whole_module(info); - if (ret) - goto sec_clk_disable; - - ret = sec_hw_init(info); - if (ret) - goto sec_clk_disable; - - return 0; - -sec_clk_disable: - sec_clk_dis(info); - - return ret; -} - -static void sec_base_exit(struct sec_dev_info *info) -{ - sec_hw_exit(info); - sec_clk_dis(info); -} - -#define SEC_Q_CMD_SIZE \ - round_up(SEC_QUEUE_LEN * sizeof(struct sec_bd_info), PAGE_SIZE) -#define SEC_Q_CQ_SIZE \ - round_up(SEC_QUEUE_LEN * sizeof(struct sec_out_bd_info), PAGE_SIZE) -#define SEC_Q_DB_SIZE \ - round_up(SEC_QUEUE_LEN * sizeof(struct sec_debug_bd_info), PAGE_SIZE) - -static int sec_queue_res_cfg(struct sec_queue *queue) -{ - struct device *dev = queue->dev_info->dev; - struct sec_queue_ring_cmd *ring_cmd = &queue->ring_cmd; - struct sec_queue_ring_cq *ring_cq = &queue->ring_cq; - struct sec_queue_ring_db *ring_db = &queue->ring_db; - int ret; - - ring_cmd->vaddr = dma_alloc_coherent(dev, SEC_Q_CMD_SIZE, - &ring_cmd->paddr, GFP_KERNEL); - if (!ring_cmd->vaddr) - return -ENOMEM; - - atomic_set(&ring_cmd->used, 0); - mutex_init(&ring_cmd->lock); - ring_cmd->callback = sec_alg_callback; - - ring_cq->vaddr = dma_alloc_coherent(dev, SEC_Q_CQ_SIZE, - &ring_cq->paddr, GFP_KERNEL); - if (!ring_cq->vaddr) { - ret = -ENOMEM; - goto err_free_ring_cmd; - } - - ring_db->vaddr = dma_alloc_coherent(dev, SEC_Q_DB_SIZE, - &ring_db->paddr, GFP_KERNEL); - if (!ring_db->vaddr) { - ret = -ENOMEM; - goto err_free_ring_cq; - } - queue->task_irq = platform_get_irq(to_platform_device(dev), - queue->queue_id * 2 + 1); - if (queue->task_irq < 0) { - ret = queue->task_irq; - goto err_free_ring_db; - } - - return 0; - -err_free_ring_db: - dma_free_coherent(dev, SEC_Q_DB_SIZE, queue->ring_db.vaddr, - queue->ring_db.paddr); -err_free_ring_cq: - dma_free_coherent(dev, SEC_Q_CQ_SIZE, queue->ring_cq.vaddr, - queue->ring_cq.paddr); -err_free_ring_cmd: - dma_free_coherent(dev, SEC_Q_CMD_SIZE, queue->ring_cmd.vaddr, - queue->ring_cmd.paddr); - - return ret; -} - -static void sec_queue_free_ring_pages(struct sec_queue *queue) -{ - struct device *dev = queue->dev_info->dev; - - dma_free_coherent(dev, SEC_Q_DB_SIZE, queue->ring_db.vaddr, - queue->ring_db.paddr); - dma_free_coherent(dev, SEC_Q_CQ_SIZE, queue->ring_cq.vaddr, - queue->ring_cq.paddr); - dma_free_coherent(dev, SEC_Q_CMD_SIZE, queue->ring_cmd.vaddr, - queue->ring_cmd.paddr); -} - -static int sec_queue_config(struct sec_dev_info *info, struct sec_queue *queue, - int queue_id) -{ - int ret; - - sec_queue_base_init(info, queue, queue_id); - - ret = sec_queue_res_cfg(queue); - if (ret) - return ret; - - ret = sec_queue_map_io(queue); - if (ret) { - dev_err(info->dev, "Queue map failed %d\n", ret); - sec_queue_free_ring_pages(queue); - return ret; - } - - sec_queue_hw_init(queue); - - return 0; -} - -static void sec_queue_unconfig(struct sec_dev_info *info, - struct sec_queue *queue) -{ - sec_queue_unmap_io(queue); - sec_queue_free_ring_pages(queue); -} - -static int sec_id_alloc(struct sec_dev_info *info) -{ - int ret = 0; - int i; - - mutex_lock(&sec_id_lock); - - for (i = 0; i < SEC_MAX_DEVICES; i++) - if (!sec_devices[i]) - break; - if (i == SEC_MAX_DEVICES) { - ret = -ENOMEM; - goto unlock; - } - info->sec_id = i; - sec_devices[info->sec_id] = info; - -unlock: - mutex_unlock(&sec_id_lock); - - return ret; -} - -static void sec_id_free(struct sec_dev_info *info) -{ - mutex_lock(&sec_id_lock); - sec_devices[info->sec_id] = NULL; - mutex_unlock(&sec_id_lock); -} - -static int sec_probe(struct platform_device *pdev) -{ - struct sec_dev_info *info; - struct device *dev = &pdev->dev; - int i, j; - int ret; - - ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64)); - if (ret) { - dev_err(dev, "Failed to set 64 bit dma mask %d", ret); - return -ENODEV; - } - - info = devm_kzalloc(dev, (sizeof(*info)), GFP_KERNEL); - if (!info) - return -ENOMEM; - - info->dev = dev; - mutex_init(&info->dev_lock); - - info->hw_sgl_pool = dmam_pool_create("sgl", dev, - sizeof(struct sec_hw_sgl), 64, 0); - if (!info->hw_sgl_pool) { - dev_err(dev, "Failed to create sec sgl dma pool\n"); - return -ENOMEM; - } - - ret = sec_base_init(info, pdev); - if (ret) { - dev_err(dev, "Base initialization fail! %d\n", ret); - return ret; - } - - for (i = 0; i < SEC_Q_NUM; i++) { - ret = sec_queue_config(info, &info->queues[i], i); - if (ret) - goto queues_unconfig; - - ret = sec_queue_irq_init(&info->queues[i]); - if (ret) { - sec_queue_unconfig(info, &info->queues[i]); - goto queues_unconfig; - } - } - - ret = sec_algs_register(); - if (ret) { - dev_err(dev, "Failed to register algorithms with crypto %d\n", - ret); - goto queues_unconfig; - } - - platform_set_drvdata(pdev, info); - - ret = sec_id_alloc(info); - if (ret) - goto algs_unregister; - - return 0; - -algs_unregister: - sec_algs_unregister(); -queues_unconfig: - for (j = i - 1; j >= 0; j--) { - sec_queue_irq_uninit(&info->queues[j]); - sec_queue_unconfig(info, &info->queues[j]); - } - sec_base_exit(info); - - return ret; -} - -static void sec_remove(struct platform_device *pdev) -{ - struct sec_dev_info *info = platform_get_drvdata(pdev); - int i; - - /* Unexpose as soon as possible, reuse during remove is fine */ - sec_id_free(info); - - sec_algs_unregister(); - - for (i = 0; i < SEC_Q_NUM; i++) { - sec_queue_irq_uninit(&info->queues[i]); - sec_queue_unconfig(info, &info->queues[i]); - } - - sec_base_exit(info); -} - -static const __maybe_unused struct of_device_id sec_match[] = { - { .compatible = "hisilicon,hip06-sec" }, - { .compatible = "hisilicon,hip07-sec" }, - {} -}; -MODULE_DEVICE_TABLE(of, sec_match); - -static const __maybe_unused struct acpi_device_id sec_acpi_match[] = { - { "HISI02C1", 0 }, - { } -}; -MODULE_DEVICE_TABLE(acpi, sec_acpi_match); - -static struct platform_driver sec_driver = { - .probe = sec_probe, - .remove = sec_remove, - .driver = { - .name = "hisi_sec_platform_driver", - .of_match_table = sec_match, - .acpi_match_table = ACPI_PTR(sec_acpi_match), - }, -}; -module_platform_driver(sec_driver); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("HiSilicon Security Accelerators"); -MODULE_AUTHOR("Zaibo Xu <xuzaibo@huawei.com"); -MODULE_AUTHOR("Jonathan Cameron <jonathan.cameron@huawei.com>"); diff --git a/drivers/crypto/hisilicon/sec/sec_drv.h b/drivers/crypto/hisilicon/sec/sec_drv.h deleted file mode 100644 index e2a50bf2234b..000000000000 --- a/drivers/crypto/hisilicon/sec/sec_drv.h +++ /dev/null @@ -1,428 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright (c) 2016-2017 HiSilicon Limited. */ - -#ifndef _SEC_DRV_H_ -#define _SEC_DRV_H_ - -#include <crypto/algapi.h> -#include <linux/kfifo.h> - -#define SEC_MAX_SGE_NUM 64 -#define SEC_HW_RING_NUM 3 - -#define SEC_CMD_RING 0 -#define SEC_OUTORDER_RING 1 -#define SEC_DBG_RING 2 - -/* A reasonable length to balance memory use against flexibility */ -#define SEC_QUEUE_LEN 512 - -#define SEC_MAX_SGE_NUM 64 - -struct sec_bd_info { -#define SEC_BD_W0_T_LEN_M GENMASK(4, 0) -#define SEC_BD_W0_T_LEN_S 0 - -#define SEC_BD_W0_C_WIDTH_M GENMASK(6, 5) -#define SEC_BD_W0_C_WIDTH_S 5 -#define SEC_C_WIDTH_AES_128BIT 0 -#define SEC_C_WIDTH_AES_8BIT 1 -#define SEC_C_WIDTH_AES_1BIT 2 -#define SEC_C_WIDTH_DES_64BIT 0 -#define SEC_C_WIDTH_DES_8BIT 1 -#define SEC_C_WIDTH_DES_1BIT 2 - -#define SEC_BD_W0_C_MODE_M GENMASK(9, 7) -#define SEC_BD_W0_C_MODE_S 7 -#define SEC_C_MODE_ECB 0 -#define SEC_C_MODE_CBC 1 -#define SEC_C_MODE_CTR 4 -#define SEC_C_MODE_CCM 5 -#define SEC_C_MODE_GCM 6 -#define SEC_C_MODE_XTS 7 - -#define SEC_BD_W0_SEQ BIT(10) -#define SEC_BD_W0_DE BIT(11) -#define SEC_BD_W0_DAT_SKIP_M GENMASK(13, 12) -#define SEC_BD_W0_DAT_SKIP_S 12 -#define SEC_BD_W0_C_GRAN_SIZE_19_16_M GENMASK(17, 14) -#define SEC_BD_W0_C_GRAN_SIZE_19_16_S 14 - -#define SEC_BD_W0_CIPHER_M GENMASK(19, 18) -#define SEC_BD_W0_CIPHER_S 18 -#define SEC_CIPHER_NULL 0 -#define SEC_CIPHER_ENCRYPT 1 -#define SEC_CIPHER_DECRYPT 2 - -#define SEC_BD_W0_AUTH_M GENMASK(21, 20) -#define SEC_BD_W0_AUTH_S 20 -#define SEC_AUTH_NULL 0 -#define SEC_AUTH_MAC 1 -#define SEC_AUTH_VERIF 2 - -#define SEC_BD_W0_AI_GEN BIT(22) -#define SEC_BD_W0_CI_GEN BIT(23) -#define SEC_BD_W0_NO_HPAD BIT(24) -#define SEC_BD_W0_HM_M GENMASK(26, 25) -#define SEC_BD_W0_HM_S 25 -#define SEC_BD_W0_ICV_OR_SKEY_EN_M GENMASK(28, 27) -#define SEC_BD_W0_ICV_OR_SKEY_EN_S 27 - -/* Multi purpose field - gran size bits for send, flag for recv */ -#define SEC_BD_W0_FLAG_M GENMASK(30, 29) -#define SEC_BD_W0_C_GRAN_SIZE_21_20_M GENMASK(30, 29) -#define SEC_BD_W0_FLAG_S 29 -#define SEC_BD_W0_C_GRAN_SIZE_21_20_S 29 - -#define SEC_BD_W0_DONE BIT(31) - u32 w0; - -#define SEC_BD_W1_AUTH_GRAN_SIZE_M GENMASK(21, 0) -#define SEC_BD_W1_AUTH_GRAN_SIZE_S 0 -#define SEC_BD_W1_M_KEY_EN BIT(22) -#define SEC_BD_W1_BD_INVALID BIT(23) -#define SEC_BD_W1_ADDR_TYPE BIT(24) - -#define SEC_BD_W1_A_ALG_M GENMASK(28, 25) -#define SEC_BD_W1_A_ALG_S 25 -#define SEC_A_ALG_SHA1 0 -#define SEC_A_ALG_SHA256 1 -#define SEC_A_ALG_MD5 2 -#define SEC_A_ALG_SHA224 3 -#define SEC_A_ALG_HMAC_SHA1 8 -#define SEC_A_ALG_HMAC_SHA224 10 -#define SEC_A_ALG_HMAC_SHA256 11 -#define SEC_A_ALG_HMAC_MD5 12 -#define SEC_A_ALG_AES_XCBC 13 -#define SEC_A_ALG_AES_CMAC 14 - -#define SEC_BD_W1_C_ALG_M GENMASK(31, 29) -#define SEC_BD_W1_C_ALG_S 29 -#define SEC_C_ALG_DES 0 -#define SEC_C_ALG_3DES 1 -#define SEC_C_ALG_AES 2 - - u32 w1; - -#define SEC_BD_W2_C_GRAN_SIZE_15_0_M GENMASK(15, 0) -#define SEC_BD_W2_C_GRAN_SIZE_15_0_S 0 -#define SEC_BD_W2_GRAN_NUM_M GENMASK(31, 16) -#define SEC_BD_W2_GRAN_NUM_S 16 - u32 w2; - -#define SEC_BD_W3_AUTH_LEN_OFFSET_M GENMASK(9, 0) -#define SEC_BD_W3_AUTH_LEN_OFFSET_S 0 -#define SEC_BD_W3_CIPHER_LEN_OFFSET_M GENMASK(19, 10) -#define SEC_BD_W3_CIPHER_LEN_OFFSET_S 10 -#define SEC_BD_W3_MAC_LEN_M GENMASK(24, 20) -#define SEC_BD_W3_MAC_LEN_S 20 -#define SEC_BD_W3_A_KEY_LEN_M GENMASK(29, 25) -#define SEC_BD_W3_A_KEY_LEN_S 25 -#define SEC_BD_W3_C_KEY_LEN_M GENMASK(31, 30) -#define SEC_BD_W3_C_KEY_LEN_S 30 -#define SEC_KEY_LEN_AES_128 0 -#define SEC_KEY_LEN_AES_192 1 -#define SEC_KEY_LEN_AES_256 2 -#define SEC_KEY_LEN_DES 1 -#define SEC_KEY_LEN_3DES_3_KEY 1 -#define SEC_KEY_LEN_3DES_2_KEY 3 - u32 w3; - - /* W4,5 */ - union { - u32 authkey_addr_lo; - u32 authiv_addr_lo; - }; - union { - u32 authkey_addr_hi; - u32 authiv_addr_hi; - }; - - /* W6,7 */ - u32 cipher_key_addr_lo; - u32 cipher_key_addr_hi; - - /* W8,9 */ - u32 cipher_iv_addr_lo; - u32 cipher_iv_addr_hi; - - /* W10,11 */ - u32 data_addr_lo; - u32 data_addr_hi; - - /* W12,13 */ - u32 mac_addr_lo; - u32 mac_addr_hi; - - /* W14,15 */ - u32 cipher_destin_addr_lo; - u32 cipher_destin_addr_hi; -}; - -enum sec_mem_region { - SEC_COMMON = 0, - SEC_SAA, - SEC_NUM_ADDR_REGIONS -}; - -#define SEC_NAME_SIZE 64 -#define SEC_Q_NUM 16 - - -/** - * struct sec_queue_ring_cmd - store information about a SEC HW cmd ring - * @used: Local counter used to cheaply establish if the ring is empty. - * @lock: Protect against simultaneous adjusting of the read and write pointers. - * @vaddr: Virtual address for the ram pages used for the ring. - * @paddr: Physical address of the dma mapped region of ram used for the ring. - * @callback: Callback function called on a ring element completing. - */ -struct sec_queue_ring_cmd { - atomic_t used; - struct mutex lock; - struct sec_bd_info *vaddr; - dma_addr_t paddr; - void (*callback)(struct sec_bd_info *resp, void *ctx); -}; - -struct sec_debug_bd_info; -struct sec_queue_ring_db { - struct sec_debug_bd_info *vaddr; - dma_addr_t paddr; -}; - -struct sec_out_bd_info; -struct sec_queue_ring_cq { - struct sec_out_bd_info *vaddr; - dma_addr_t paddr; -}; - -struct sec_dev_info; - -enum sec_cipher_alg { - SEC_C_DES_ECB_64, - SEC_C_DES_CBC_64, - - SEC_C_3DES_ECB_192_3KEY, - SEC_C_3DES_ECB_192_2KEY, - - SEC_C_3DES_CBC_192_3KEY, - SEC_C_3DES_CBC_192_2KEY, - - SEC_C_AES_ECB_128, - SEC_C_AES_ECB_192, - SEC_C_AES_ECB_256, - - SEC_C_AES_CBC_128, - SEC_C_AES_CBC_192, - SEC_C_AES_CBC_256, - - SEC_C_AES_CTR_128, - SEC_C_AES_CTR_192, - SEC_C_AES_CTR_256, - - SEC_C_AES_XTS_128, - SEC_C_AES_XTS_256, - - SEC_C_NULL, -}; - -/** - * struct sec_alg_tfm_ctx - hardware specific tranformation context - * @cipher_alg: Cipher algorithm enabled include encryption mode. - * @key: Key storage if required. - * @pkey: DMA address for the key storage. - * @req_template: Request template to save time on setup. - * @queue: The hardware queue associated with this tfm context. - * @lock: Protect key and pkey to ensure they are consistent - * @auth_buf: Current context buffer for auth operations. - * @backlog: The backlog queue used for cases where our buffers aren't - * large enough. - */ -struct sec_alg_tfm_ctx { - enum sec_cipher_alg cipher_alg; - u8 *key; - dma_addr_t pkey; - struct sec_bd_info req_template; - struct sec_queue *queue; - struct mutex lock; - u8 *auth_buf; - struct list_head backlog; -}; - -/** - * struct sec_request - data associate with a single crypto request - * @elements: List of subparts of this request (hardware size restriction) - * @num_elements: The number of subparts (used as an optimization) - * @lock: Protect elements of this structure against concurrent change. - * @tfm_ctx: hardware specific context. - * @len_in: length of in sgl from upper layers - * @len_out: length of out sgl from upper layers - * @dma_iv: initialization vector - phsyical address - * @err: store used to track errors across subelements of this request. - * @req_base: pointer to base element of associate crypto context. - * This is needed to allow shared handling skcipher, ahash etc. - * @cb: completion callback. - * @backlog_head: list head to allow backlog maintenance. - * - * The hardware is limited in the maximum size of data that it can - * process from a single BD. Typically this is fairly large (32MB) - * but still requires the complexity of splitting the incoming - * skreq up into a number of elements complete with appropriate - * iv chaining. - */ -struct sec_request { - struct list_head elements; - int num_elements; - struct mutex lock; - struct sec_alg_tfm_ctx *tfm_ctx; - int len_in; - int len_out; - dma_addr_t dma_iv; - int err; - struct crypto_async_request *req_base; - void (*cb)(struct sec_bd_info *resp, struct crypto_async_request *req); - struct list_head backlog_head; -}; - -/** - * struct sec_request_el - A subpart of a request. - * @head: allow us to attach this to the list in the sec_request - * @req: hardware block descriptor corresponding to this request subpart - * @in: hardware sgl for input - virtual address - * @dma_in: hardware sgl for input - physical address - * @sgl_in: scatterlist for this request subpart - * @out: hardware sgl for output - virtual address - * @dma_out: hardware sgl for output - physical address - * @sgl_out: scatterlist for this request subpart - * @sec_req: The request which this subpart forms a part of - * @el_length: Number of bytes in this subpart. Needed to locate - * last ivsize chunk for iv chaining. - */ -struct sec_request_el { - struct list_head head; - struct sec_bd_info req; - struct sec_hw_sgl *in; - dma_addr_t dma_in; - struct scatterlist *sgl_in; - struct sec_hw_sgl *out; - dma_addr_t dma_out; - struct scatterlist *sgl_out; - struct sec_request *sec_req; - size_t el_length; -}; - -/** - * struct sec_queue - All the information about a HW queue - * @dev_info: The parent SEC device to which this queue belongs. - * @task_irq: Completion interrupt for the queue. - * @name: Human readable queue description also used as irq name. - * @ring: The several HW rings associated with one queue. - * @regs: The iomapped device registers - * @queue_id: Index of the queue used for naming and resource selection. - * @in_use: Flag to say if the queue is in use. - * @expected: The next expected element to finish assuming we were in order. - * @uprocessed: A bitmap to track which OoO elements are done but not handled. - * @softqueue: A software queue used when chaining requirements prevent direct - * use of the hardware queues. - * @havesoftqueue: A flag to say we have a queues - as we may need one for the - * current mode. - * @queuelock: Protect the soft queue from concurrent changes to avoid some - * potential loss of data races. - * @shadow: Pointers back to the shadow copy of the hardware ring element - * need because we can't store any context reference in the bd element. - */ -struct sec_queue { - struct sec_dev_info *dev_info; - int task_irq; - char name[SEC_NAME_SIZE]; - struct sec_queue_ring_cmd ring_cmd; - struct sec_queue_ring_cq ring_cq; - struct sec_queue_ring_db ring_db; - void __iomem *regs; - u32 queue_id; - bool in_use; - int expected; - - DECLARE_BITMAP(unprocessed, SEC_QUEUE_LEN); - DECLARE_KFIFO_PTR(softqueue, typeof(struct sec_request_el *)); - bool havesoftqueue; - spinlock_t queuelock; - void *shadow[SEC_QUEUE_LEN]; -}; - -/** - * struct sec_hw_sge: Track each of the 64 element SEC HW SGL entries - * @buf: The IOV dma address for this entry. - * @len: Length of this IOV. - * @pad: Reserved space. - */ -struct sec_hw_sge { - dma_addr_t buf; - unsigned int len; - unsigned int pad; -}; - -/** - * struct sec_hw_sgl: One hardware SGL entry. - * @next_sgl: The next entry if we need to chain dma address. Null if last. - * @entry_sum_in_chain: The full count of SGEs - only matters for first SGL. - * @entry_sum_in_sgl: The number of SGEs in this SGL element. - * @flag: Unused in skciphers. - * @serial_num: Unsued in skciphers. - * @cpuid: Currently unused. - * @data_bytes_in_sgl: Count of bytes from all SGEs in this SGL. - * @next: Virtual address used to stash the next sgl - useful in completion. - * @reserved: A reserved field not currently used. - * @sge_entries: The (up to) 64 Scatter Gather Entries, representing IOVs. - * @node: Currently unused. - */ -struct sec_hw_sgl { - dma_addr_t next_sgl; - u16 entry_sum_in_chain; - u16 entry_sum_in_sgl; - u32 flag; - u64 serial_num; - u32 cpuid; - u32 data_bytes_in_sgl; - struct sec_hw_sgl *next; - u64 reserved; - struct sec_hw_sge sge_entries[SEC_MAX_SGE_NUM]; - u8 node[16]; -}; - -struct dma_pool; - -/** - * struct sec_dev_info: The full SEC unit comprising queues and processors. - * @sec_id: Index used to track which SEC this is when more than one is present. - * @num_saas: The number of backed processors enabled. - * @regs: iomapped register regions shared by whole SEC unit. - * @dev_lock: Protects concurrent queue allocation / freeing for the SEC. - * @queues: The 16 queues that this SEC instance provides. - * @dev: Device pointer. - * @hw_sgl_pool: DMA pool used to mimise mapping for the scatter gather lists. - */ -struct sec_dev_info { - int sec_id; - int num_saas; - void __iomem *regs[SEC_NUM_ADDR_REGIONS]; - struct mutex dev_lock; - int queues_in_use; - struct sec_queue queues[SEC_Q_NUM]; - struct device *dev; - struct dma_pool *hw_sgl_pool; -}; - -int sec_queue_send(struct sec_queue *queue, struct sec_bd_info *msg, void *ctx); -bool sec_queue_can_enqueue(struct sec_queue *queue, int num); -int sec_queue_stop_release(struct sec_queue *queue); -struct sec_queue *sec_queue_alloc_start_safe(void); -bool sec_queue_empty(struct sec_queue *queue); - -/* Algorithm specific elements from sec_algs.c */ -void sec_alg_callback(struct sec_bd_info *resp, void *ctx); -int sec_algs_register(void); -void sec_algs_unregister(void); - -#endif /* _SEC_DRV_H_ */ diff --git a/drivers/crypto/hisilicon/sec2/sec_main.c b/drivers/crypto/hisilicon/sec2/sec_main.c index 03523cfbb28e..1e0412c70c72 100644 --- a/drivers/crypto/hisilicon/sec2/sec_main.c +++ b/drivers/crypto/hisilicon/sec2/sec_main.c @@ -1285,8 +1285,8 @@ static int sec_pre_store_cap_reg(struct hisi_qm *qm) i, qm->cap_ver); } - qm->cap_tables.dev_cap_table = sec_cap; qm->cap_tables.dev_cap_size = size; + qm->cap_tables.dev_cap_table = sec_cap; return 0; } diff --git a/drivers/crypto/hisilicon/zip/dae_main.c b/drivers/crypto/hisilicon/zip/dae_main.c index 68aebd02fc84..57ea836a265e 100644 --- a/drivers/crypto/hisilicon/zip/dae_main.c +++ b/drivers/crypto/hisilicon/zip/dae_main.c @@ -39,6 +39,8 @@ #define DAE_AM_RETURN_MASK 0x3 #define DAE_AXI_CFG_OFFSET 0x331000 #define DAE_AXI_SHUTDOWN_EN_MASK (BIT(0) | BIT(5)) +#define DAE_AUTO_CG_EN_OFFSET 0x331070 +#define DAE_AUTO_CG_EN_MASK (~(BIT_ULL(4) | BIT_ULL(18) | BIT_ULL(19))) struct hisi_dae_hw_error { u32 int_msk; @@ -61,6 +63,17 @@ static inline bool dae_is_support(struct hisi_qm *qm) return false; } +static void hisi_dae_set_clock_gating(struct hisi_qm *qm, bool enable) +{ + if (qm->ver < QM_HW_V5) + return; + + if (enable) + writeq(DAE_AUTO_CG_EN_MASK, qm->io_base + DAE_AUTO_CG_EN_OFFSET); + else + writeq(0, qm->io_base + DAE_AUTO_CG_EN_OFFSET); +} + int hisi_dae_set_user_domain(struct hisi_qm *qm) { u32 val; @@ -69,16 +82,22 @@ int hisi_dae_set_user_domain(struct hisi_qm *qm) if (!dae_is_support(qm)) return 0; + hisi_dae_set_clock_gating(qm, false); + val = readl(qm->io_base + DAE_MEM_START_OFFSET); val |= DAE_MEM_START_MASK; writel(val, qm->io_base + DAE_MEM_START_OFFSET); ret = readl_relaxed_poll_timeout(qm->io_base + DAE_MEM_DONE_OFFSET, val, val & DAE_MEM_DONE_MASK, DAE_REG_RD_INTVRL_US, DAE_REG_RD_TMOUT_US); - if (ret) + if (ret) { pci_err(qm->pdev, "failed to init dae memory!\n"); + return ret; + } - return ret; + hisi_dae_set_clock_gating(qm, true); + + return 0; } int hisi_dae_set_alg(struct hisi_qm *qm) diff --git a/drivers/crypto/hisilicon/zip/zip_main.c b/drivers/crypto/hisilicon/zip/zip_main.c index 706a73656977..10091ad4a6a8 100644 --- a/drivers/crypto/hisilicon/zip/zip_main.c +++ b/drivers/crypto/hisilicon/zip/zip_main.c @@ -1400,8 +1400,8 @@ static int zip_pre_store_cap_reg(struct hisi_qm *qm) i, qm->cap_ver); } - qm->cap_tables.dev_cap_table = zip_cap; qm->cap_tables.dev_cap_size = size; + qm->cap_tables.dev_cap_table = zip_cap; return 0; } diff --git a/drivers/crypto/inside-secure/eip93/eip93-aead.c b/drivers/crypto/inside-secure/eip93/eip93-aead.c index 2bbd0af7b0e0..0b7a899b14d7 100644 --- a/drivers/crypto/inside-secure/eip93/eip93-aead.c +++ b/drivers/crypto/inside-secure/eip93/eip93-aead.c @@ -92,7 +92,6 @@ static int eip93_aead_setkey(struct crypto_aead *ctfm, const u8 *key, struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); struct eip93_crypto_ctx *ctx = crypto_tfm_ctx(tfm); struct crypto_authenc_keys keys; - struct crypto_aes_ctx aes; struct sa_record *sa_record = ctx->sa_record; u32 nonce = 0; int ret; @@ -126,7 +125,7 @@ static int eip93_aead_setkey(struct crypto_aead *ctfm, const u8 *key, break; case EIP93_ALG_AES: - ret = aes_expandkey(&aes, keys.enckey, keys.enckeylen); + ret = aes_check_keylen(keys.enckeylen); if (ret) return ret; diff --git a/drivers/crypto/inside-secure/eip93/eip93-regs.h b/drivers/crypto/inside-secure/eip93/eip93-regs.h index 96d28c6651bd..1d726bcdd77f 100644 --- a/drivers/crypto/inside-secure/eip93/eip93-regs.h +++ b/drivers/crypto/inside-secure/eip93/eip93-regs.h @@ -281,7 +281,7 @@ #define EIP93_SA_CMD_HASH_CRYPT_OFFSET GENMASK(23, 16) #define EIP93_SA_CMD_BYTE_OFFSET BIT(13) /* 0: CRYPT_OFFSET in 32bit word 1: CRYPT_OFFSET in 8bit bytes */ #define EIP93_SA_CMD_HMAC BIT(12) -#define EIP93_SA_CMD_SSL_MAC BIT(12) +#define EIP93_SA_CMD_SSL_MAC BIT(11) /* This mask can be either used for ARC4 or AES */ #define EIP93_SA_CMD_CHIPER_MODE GENMASK(9, 8) /* AES or DES operations */ diff --git a/drivers/crypto/inside-secure/safexcel_cipher.c b/drivers/crypto/inside-secure/safexcel_cipher.c index a8349b684693..b031cb9652ec 100644 --- a/drivers/crypto/inside-secure/safexcel_cipher.c +++ b/drivers/crypto/inside-secure/safexcel_cipher.c @@ -375,7 +375,7 @@ static int safexcel_skcipher_aes_setkey(struct crypto_skcipher *ctfm, struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm); struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); struct safexcel_crypto_priv *priv = ctx->base.priv; - struct crypto_aes_ctx aes; + struct crypto_aes_ctx aes __cleanup(aes_zeroize_ctx); int ret, i; ret = aes_expandkey(&aes, key, len); @@ -396,7 +396,6 @@ static int safexcel_skcipher_aes_setkey(struct crypto_skcipher *ctfm, ctx->key_len = len; - memzero_explicit(&aes, sizeof(aes)); return 0; } @@ -407,7 +406,6 @@ static int safexcel_aead_setkey(struct crypto_aead *ctfm, const u8 *key, struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); struct safexcel_crypto_priv *priv = ctx->base.priv; struct crypto_authenc_keys keys; - struct crypto_aes_ctx aes; int err = -EINVAL, i; const char *alg; @@ -438,7 +436,7 @@ static int safexcel_aead_setkey(struct crypto_aead *ctfm, const u8 *key, goto badkey; break; case SAFEXCEL_AES: - err = aes_expandkey(&aes, keys.enckey, keys.enckeylen); + err = aes_check_keylen(keys.enckeylen); if (unlikely(err)) goto badkey; break; @@ -1362,7 +1360,7 @@ static int safexcel_skcipher_aesctr_setkey(struct crypto_skcipher *ctfm, struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm); struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); struct safexcel_crypto_priv *priv = ctx->base.priv; - struct crypto_aes_ctx aes; + struct crypto_aes_ctx aes __cleanup(aes_zeroize_ctx); int ret, i; unsigned int keylen; @@ -1388,7 +1386,6 @@ static int safexcel_skcipher_aesctr_setkey(struct crypto_skcipher *ctfm, ctx->key_len = keylen; - memzero_explicit(&aes, sizeof(aes)); return 0; } @@ -2542,7 +2539,7 @@ static int safexcel_skcipher_aesxts_setkey(struct crypto_skcipher *ctfm, struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm); struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); struct safexcel_crypto_priv *priv = ctx->base.priv; - struct crypto_aes_ctx aes; + struct crypto_aes_ctx aes __cleanup(aes_zeroize_ctx); int ret, i; unsigned int keylen; @@ -2590,7 +2587,6 @@ static int safexcel_skcipher_aesxts_setkey(struct crypto_skcipher *ctfm, ctx->key_len = keylen << 1; - memzero_explicit(&aes, sizeof(aes)); return 0; } @@ -2756,12 +2752,11 @@ static int safexcel_aead_ccm_setkey(struct crypto_aead *ctfm, const u8 *key, struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); struct safexcel_crypto_priv *priv = ctx->base.priv; - struct crypto_aes_ctx aes; + struct crypto_aes_ctx aes __cleanup(aes_zeroize_ctx); int ret, i; ret = aes_expandkey(&aes, key, len); if (ret) { - memzero_explicit(&aes, sizeof(aes)); return ret; } @@ -2790,7 +2785,6 @@ static int safexcel_aead_ccm_setkey(struct crypto_aead *ctfm, const u8 *key, else ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC128; - memzero_explicit(&aes, sizeof(aes)); return 0; } diff --git a/drivers/crypto/inside-secure/safexcel_hash.c b/drivers/crypto/inside-secure/safexcel_hash.c index 3402e570d045..8f107da66685 100644 --- a/drivers/crypto/inside-secure/safexcel_hash.c +++ b/drivers/crypto/inside-secure/safexcel_hash.c @@ -1905,7 +1905,7 @@ static int safexcel_cbcmac_setkey(struct crypto_ahash *tfm, const u8 *key, unsigned int len) { struct safexcel_ahash_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm)); - struct crypto_aes_ctx aes; + struct crypto_aes_ctx aes __cleanup(aes_zeroize_ctx); int ret, i; ret = aes_expandkey(&aes, key, len); @@ -1928,7 +1928,6 @@ static int safexcel_cbcmac_setkey(struct crypto_ahash *tfm, const u8 *key, } ctx->cbcmac = true; - memzero_explicit(&aes, sizeof(aes)); return 0; } @@ -1993,6 +1992,7 @@ static int safexcel_xcbcmac_setkey(struct crypto_ahash *tfm, const u8 *key, ret = aes_prepareenckey(ctx->aes, (u8 *)key_tmp + 2 * AES_BLOCK_SIZE, AES_MIN_KEY_SIZE); + memzero_explicit(key_tmp, sizeof(key_tmp)); if (ret) return ret; @@ -2104,6 +2104,8 @@ static int safexcel_cmac_setkey(struct crypto_ahash *tfm, const u8 *key, } ctx->cbcmac = false; + memzero_explicit(consts, sizeof(consts)); + memzero_explicit(_const, sizeof(_const)); return 0; } diff --git a/drivers/crypto/intel/ixp4xx/ixp4xx_crypto.c b/drivers/crypto/intel/ixp4xx/ixp4xx_crypto.c index fdda04672454..33e8e887a415 100644 --- a/drivers/crypto/intel/ixp4xx/ixp4xx_crypto.c +++ b/drivers/crypto/intel/ixp4xx/ixp4xx_crypto.c @@ -707,8 +707,7 @@ static int register_chain_var(struct crypto_tfm *tfm, u8 xpad, u32 target, return -EAGAIN; } - memcpy(pad, key, key_len); - memset(pad + key_len, 0, HMAC_PAD_BLOCKLEN - key_len); + memcpy_and_pad(pad, HMAC_PAD_BLOCKLEN, key, key_len, 0); for (i = 0; i < HMAC_PAD_BLOCKLEN; i++) pad[i] ^= xpad; diff --git a/drivers/crypto/intel/qat/qat_420xx/adf_420xx_hw_data.c b/drivers/crypto/intel/qat/qat_420xx/adf_420xx_hw_data.c index 19f9f738630b..d6f1f626cf5a 100644 --- a/drivers/crypto/intel/qat/qat_420xx/adf_420xx_hw_data.c +++ b/drivers/crypto/intel/qat/qat_420xx/adf_420xx_hw_data.c @@ -443,7 +443,6 @@ void adf_init_hw_data_420xx(struct adf_hw_device_data *hw_data, u32 dev_id) hw_data->enable_error_correction = adf_gen4_enable_error_correction; hw_data->get_accel_mask = adf_gen4_get_accel_mask; hw_data->get_ae_mask = get_ae_mask; - hw_data->get_num_accels = adf_gen4_get_num_accels; hw_data->get_num_aes = adf_gen4_get_num_aes; hw_data->get_sram_bar_id = adf_gen4_get_sram_bar_id; hw_data->get_etr_bar_id = adf_gen4_get_etr_bar_id; diff --git a/drivers/crypto/intel/qat/qat_4xxx/adf_4xxx_hw_data.c b/drivers/crypto/intel/qat/qat_4xxx/adf_4xxx_hw_data.c index 49b425be34c8..7d9dd44ca477 100644 --- a/drivers/crypto/intel/qat/qat_4xxx/adf_4xxx_hw_data.c +++ b/drivers/crypto/intel/qat/qat_4xxx/adf_4xxx_hw_data.c @@ -412,7 +412,6 @@ void adf_init_hw_data_4xxx(struct adf_hw_device_data *hw_data, u32 dev_id) hw_data->enable_error_correction = adf_gen4_enable_error_correction; hw_data->get_accel_mask = adf_gen4_get_accel_mask; hw_data->get_ae_mask = get_ae_mask; - hw_data->get_num_accels = adf_gen4_get_num_accels; hw_data->get_num_aes = adf_gen4_get_num_aes; hw_data->get_sram_bar_id = adf_gen4_get_sram_bar_id; hw_data->get_etr_bar_id = adf_gen4_get_etr_bar_id; diff --git a/drivers/crypto/intel/qat/qat_6xxx/adf_6xxx_hw_data.c b/drivers/crypto/intel/qat/qat_6xxx/adf_6xxx_hw_data.c index 388087e64540..ca9bc5dccf67 100644 --- a/drivers/crypto/intel/qat/qat_6xxx/adf_6xxx_hw_data.c +++ b/drivers/crypto/intel/qat/qat_6xxx/adf_6xxx_hw_data.c @@ -326,11 +326,6 @@ static u32 get_accel_mask(struct adf_hw_device_data *self) return ADF_GEN6_ACCELERATORS_MASK; } -static u32 get_num_accels(struct adf_hw_device_data *self) -{ - return ADF_GEN6_MAX_ACCELERATORS; -} - static u32 get_num_aes(struct adf_hw_device_data *self) { return self ? hweight32(self->ae_mask) : 0; @@ -1023,7 +1018,6 @@ void adf_init_hw_data_6xxx(struct adf_hw_device_data *hw_data) hw_data->enable_error_correction = enable_error_correction; hw_data->get_accel_mask = get_accel_mask; hw_data->get_ae_mask = get_ae_mask; - hw_data->get_num_accels = get_num_accels; hw_data->get_num_aes = get_num_aes; hw_data->get_sram_bar_id = get_sram_bar_id; hw_data->get_etr_bar_id = get_etr_bar_id; diff --git a/drivers/crypto/intel/qat/qat_c3xxx/adf_c3xxx_hw_data.c b/drivers/crypto/intel/qat/qat_c3xxx/adf_c3xxx_hw_data.c index 07f2c42a68f5..b9cc6c97778a 100644 --- a/drivers/crypto/intel/qat/qat_c3xxx/adf_c3xxx_hw_data.c +++ b/drivers/crypto/intel/qat/qat_c3xxx/adf_c3xxx_hw_data.c @@ -129,7 +129,6 @@ void adf_init_hw_data_c3xxx(struct adf_hw_device_data *hw_data) hw_data->get_accel_mask = get_accel_mask; hw_data->get_ae_mask = get_ae_mask; hw_data->get_accel_cap = adf_gen2_get_accel_cap; - hw_data->get_num_accels = adf_gen2_get_num_accels; hw_data->get_num_aes = adf_gen2_get_num_aes; hw_data->get_sram_bar_id = get_sram_bar_id; hw_data->get_etr_bar_id = get_etr_bar_id; diff --git a/drivers/crypto/intel/qat/qat_c3xxxvf/adf_c3xxxvf_hw_data.c b/drivers/crypto/intel/qat/qat_c3xxxvf/adf_c3xxxvf_hw_data.c index db3c33fa1881..8a5cce516436 100644 --- a/drivers/crypto/intel/qat/qat_c3xxxvf/adf_c3xxxvf_hw_data.c +++ b/drivers/crypto/intel/qat/qat_c3xxxvf/adf_c3xxxvf_hw_data.c @@ -24,11 +24,6 @@ static u32 get_ae_mask(struct adf_hw_device_data *self) return ADF_C3XXXIOV_ACCELENGINES_MASK; } -static u32 get_num_accels(struct adf_hw_device_data *self) -{ - return ADF_C3XXXIOV_MAX_ACCELERATORS; -} - static u32 get_num_aes(struct adf_hw_device_data *self) { return ADF_C3XXXIOV_MAX_ACCELENGINES; @@ -80,7 +75,6 @@ void adf_init_hw_data_c3xxxiov(struct adf_hw_device_data *hw_data) hw_data->disable_iov = adf_vf2pf_notify_shutdown; hw_data->get_accel_mask = get_accel_mask; hw_data->get_ae_mask = get_ae_mask; - hw_data->get_num_accels = get_num_accels; hw_data->get_num_aes = get_num_aes; hw_data->get_etr_bar_id = get_etr_bar_id; hw_data->get_misc_bar_id = get_misc_bar_id; diff --git a/drivers/crypto/intel/qat/qat_c62x/adf_c62x_hw_data.c b/drivers/crypto/intel/qat/qat_c62x/adf_c62x_hw_data.c index 0b410b41474d..aed1c951754a 100644 --- a/drivers/crypto/intel/qat/qat_c62x/adf_c62x_hw_data.c +++ b/drivers/crypto/intel/qat/qat_c62x/adf_c62x_hw_data.c @@ -131,7 +131,6 @@ void adf_init_hw_data_c62x(struct adf_hw_device_data *hw_data) hw_data->get_accel_mask = get_accel_mask; hw_data->get_ae_mask = get_ae_mask; hw_data->get_accel_cap = adf_gen2_get_accel_cap; - hw_data->get_num_accels = adf_gen2_get_num_accels; hw_data->get_num_aes = adf_gen2_get_num_aes; hw_data->get_sram_bar_id = get_sram_bar_id; hw_data->get_etr_bar_id = get_etr_bar_id; diff --git a/drivers/crypto/intel/qat/qat_c62xvf/adf_c62xvf_hw_data.c b/drivers/crypto/intel/qat/qat_c62xvf/adf_c62xvf_hw_data.c index 7f00035d3661..ded32eaae48d 100644 --- a/drivers/crypto/intel/qat/qat_c62xvf/adf_c62xvf_hw_data.c +++ b/drivers/crypto/intel/qat/qat_c62xvf/adf_c62xvf_hw_data.c @@ -24,11 +24,6 @@ static u32 get_ae_mask(struct adf_hw_device_data *self) return ADF_C62XIOV_ACCELENGINES_MASK; } -static u32 get_num_accels(struct adf_hw_device_data *self) -{ - return ADF_C62XIOV_MAX_ACCELERATORS; -} - static u32 get_num_aes(struct adf_hw_device_data *self) { return ADF_C62XIOV_MAX_ACCELENGINES; @@ -80,7 +75,6 @@ void adf_init_hw_data_c62xiov(struct adf_hw_device_data *hw_data) hw_data->disable_iov = adf_vf2pf_notify_shutdown; hw_data->get_accel_mask = get_accel_mask; hw_data->get_ae_mask = get_ae_mask; - hw_data->get_num_accels = get_num_accels; hw_data->get_num_aes = get_num_aes; hw_data->get_etr_bar_id = get_etr_bar_id; hw_data->get_misc_bar_id = get_misc_bar_id; diff --git a/drivers/crypto/intel/qat/qat_common/adf_accel_devices.h b/drivers/crypto/intel/qat/qat_common/adf_accel_devices.h index a84380125fe5..b77f461e8583 100644 --- a/drivers/crypto/intel/qat/qat_common/adf_accel_devices.h +++ b/drivers/crypto/intel/qat/qat_common/adf_accel_devices.h @@ -279,7 +279,6 @@ struct adf_hw_device_data { u32 (*get_misc_bar_id)(struct adf_hw_device_data *self); u32 (*get_etr_bar_id)(struct adf_hw_device_data *self); u32 (*get_num_aes)(struct adf_hw_device_data *self); - u32 (*get_num_accels)(struct adf_hw_device_data *self); void (*get_arb_info)(struct arb_info *arb_csrs_info); void (*get_admin_info)(struct admin_info *admin_csrs_info); enum dev_sku_info (*get_sku)(struct adf_hw_device_data *self); diff --git a/drivers/crypto/intel/qat/qat_common/adf_cfg.c b/drivers/crypto/intel/qat/qat_common/adf_cfg.c index b88febf53a19..e2ef5284abef 100644 --- a/drivers/crypto/intel/qat/qat_common/adf_cfg.c +++ b/drivers/crypto/intel/qat/qat_common/adf_cfg.c @@ -1,6 +1,5 @@ // SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only) /* Copyright(c) 2014 - 2020 Intel Corporation */ -#include <linux/mutex.h> #include <linux/slab.h> #include <linux/string.h> #include <linux/list.h> @@ -9,13 +8,11 @@ #include "adf_cfg.h" #include "adf_common_drv.h" -static DEFINE_MUTEX(qat_cfg_read_lock); - static void *qat_dev_cfg_start(struct seq_file *sfile, loff_t *pos) { struct adf_cfg_device_data *dev_cfg = sfile->private; - mutex_lock(&qat_cfg_read_lock); + down_read(&dev_cfg->lock); return seq_list_start(&dev_cfg->sec_list, *pos); } @@ -43,7 +40,9 @@ static void *qat_dev_cfg_next(struct seq_file *sfile, void *v, loff_t *pos) static void qat_dev_cfg_stop(struct seq_file *sfile, void *v) { - mutex_unlock(&qat_cfg_read_lock); + struct adf_cfg_device_data *dev_cfg = sfile->private; + + up_read(&dev_cfg->lock); } static const struct seq_operations qat_dev_cfg_sops = { @@ -146,24 +145,6 @@ static void adf_cfg_keyval_add(struct adf_cfg_key_val *new, list_add_tail(&new->list, &sec->param_head); } -static void adf_cfg_keyval_remove(const char *key, struct adf_cfg_section *sec) -{ - struct list_head *head = &sec->param_head; - struct list_head *list_ptr, *tmp; - - list_for_each_prev_safe(list_ptr, tmp, head) { - struct adf_cfg_key_val *ptr = - list_entry(list_ptr, struct adf_cfg_key_val, list); - - if (strncmp(ptr->key, key, sizeof(ptr->key))) - continue; - - list_del(list_ptr); - kfree(ptr); - break; - } -} - static void adf_cfg_keyval_del_all(struct list_head *head) { struct list_head *list_ptr, *tmp; @@ -272,13 +253,9 @@ int adf_cfg_add_key_value_param(struct adf_accel_dev *accel_dev, enum adf_cfg_val_type type) { struct adf_cfg_device_data *cfg = accel_dev->cfg; - struct adf_cfg_key_val *key_val; - struct adf_cfg_section *section = adf_cfg_sec_find(accel_dev, - section_name); - char temp_val[ADF_CFG_MAX_VAL_LEN_IN_BYTES]; - - if (!section) - return -EFAULT; + struct adf_cfg_key_val *key_val, *existing; + struct adf_cfg_section *section; + int ret = 0; key_val = kzalloc_obj(*key_val); if (!key_val) @@ -299,7 +276,17 @@ int adf_cfg_add_key_value_param(struct adf_accel_dev *accel_dev, } key_val->type = type; - /* Add the key-value pair as below policy: + down_write(&cfg->lock); + + section = adf_cfg_sec_find(accel_dev, section_name); + if (!section) { + kfree(key_val); + ret = -ENOENT; + goto unlock; + } + + /* + * Add the key-value pair as below policy: * 1. if the key doesn't exist, add it; * 2. if the key already exists with a different value then update it * to the new value (the key is deleted and the newly created @@ -307,21 +294,21 @@ int adf_cfg_add_key_value_param(struct adf_accel_dev *accel_dev, * 3. if the key exists with the same value, then return without doing * anything (the newly created key_val is freed). */ - down_write(&cfg->lock); - if (!adf_cfg_key_val_get(accel_dev, section_name, key, temp_val)) { - if (strncmp(temp_val, key_val->val, sizeof(temp_val))) { - adf_cfg_keyval_remove(key, section); - } else { + existing = adf_cfg_key_value_find(section, key); + if (existing) { + if (!strncmp(existing->val, key_val->val, sizeof(existing->val))) { kfree(key_val); - goto out; + goto unlock; } + list_del(&existing->list); + kfree(existing); } adf_cfg_keyval_add(key_val, section); -out: +unlock: up_write(&cfg->lock); - return 0; + return ret; } EXPORT_SYMBOL_GPL(adf_cfg_add_key_value_param); @@ -339,21 +326,26 @@ EXPORT_SYMBOL_GPL(adf_cfg_add_key_value_param); int adf_cfg_section_add(struct adf_accel_dev *accel_dev, const char *name) { struct adf_cfg_device_data *cfg = accel_dev->cfg; - struct adf_cfg_section *sec = adf_cfg_sec_find(accel_dev, name); + struct adf_cfg_section *sec; + int ret = 0; - if (sec) - return 0; + down_write(&cfg->lock); + + if (adf_cfg_sec_find(accel_dev, name)) + goto unlock; sec = kzalloc_obj(*sec); - if (!sec) - return -ENOMEM; + if (!sec) { + ret = -ENOMEM; + goto unlock; + } strscpy(sec->name, name); INIT_LIST_HEAD(&sec->param_head); - down_write(&cfg->lock); list_add_tail(&sec->list, &cfg->sec_list); +unlock: up_write(&cfg->lock); - return 0; + return ret; } EXPORT_SYMBOL_GPL(adf_cfg_section_add); diff --git a/drivers/crypto/intel/qat/qat_common/adf_dev_mgr.c b/drivers/crypto/intel/qat/qat_common/adf_dev_mgr.c index 161863841a52..4e6d860c9a60 100644 --- a/drivers/crypto/intel/qat/qat_common/adf_dev_mgr.c +++ b/drivers/crypto/intel/qat/qat_common/adf_dev_mgr.c @@ -137,6 +137,13 @@ int adf_devmgr_add_dev(struct adf_accel_dev *accel_dev, mutex_lock(&table_lock); atomic_set(&accel_dev->ref_count, 0); + mutex_init(&accel_dev->state_lock); + /* + * The VF2PF lock is used to send messages to the PF outside of the + * device up/down cycle, so it must live as long as the accel device. + */ + if (accel_dev->is_vf) + mutex_init(&accel_dev->vf.vf2pf_lock); /* PF on host or VF on guest - optimized to remove redundant is_vf */ if (!accel_dev->is_vf || !pf) { @@ -210,7 +217,6 @@ int adf_devmgr_add_dev(struct adf_accel_dev *accel_dev, map->attached = true; list_add_tail(&map->list, &vfs_table); } - mutex_init(&accel_dev->state_lock); unlock: mutex_unlock(&table_lock); return ret; @@ -257,6 +263,8 @@ void adf_devmgr_rm_dev(struct adf_accel_dev *accel_dev, } } unlock: + if (accel_dev->is_vf) + mutex_destroy(&accel_dev->vf.vf2pf_lock); mutex_destroy(&accel_dev->state_lock); list_del(&accel_dev->list); mutex_unlock(&table_lock); diff --git a/drivers/crypto/intel/qat/qat_common/adf_gen2_hw_data.c b/drivers/crypto/intel/qat/qat_common/adf_gen2_hw_data.c index 6a505e9a5cf9..bff89c8538f0 100644 --- a/drivers/crypto/intel/qat/qat_common/adf_gen2_hw_data.c +++ b/drivers/crypto/intel/qat/qat_common/adf_gen2_hw_data.c @@ -7,15 +7,6 @@ #include "icp_qat_hw.h" #include <linux/pci.h> -u32 adf_gen2_get_num_accels(struct adf_hw_device_data *self) -{ - if (!self || !self->accel_mask) - return 0; - - return hweight16(self->accel_mask); -} -EXPORT_SYMBOL_GPL(adf_gen2_get_num_accels); - u32 adf_gen2_get_num_aes(struct adf_hw_device_data *self) { if (!self || !self->ae_mask) diff --git a/drivers/crypto/intel/qat/qat_common/adf_gen2_hw_data.h b/drivers/crypto/intel/qat/qat_common/adf_gen2_hw_data.h index 59bad368a921..3caeb1d178cf 100644 --- a/drivers/crypto/intel/qat/qat_common/adf_gen2_hw_data.h +++ b/drivers/crypto/intel/qat/qat_common/adf_gen2_hw_data.h @@ -78,7 +78,6 @@ #define ADF_GEN2_SMIAPF1_MASK_OFFSET (0x3A000 + 0x30) #define ADF_GEN2_SMIA1_MASK 0x1 -u32 adf_gen2_get_num_accels(struct adf_hw_device_data *self); u32 adf_gen2_get_num_aes(struct adf_hw_device_data *self); void adf_gen2_enable_error_correction(struct adf_accel_dev *accel_dev); void adf_gen2_cfg_iov_thds(struct adf_accel_dev *accel_dev, bool enable, diff --git a/drivers/crypto/intel/qat/qat_common/adf_gen4_hw_data.c b/drivers/crypto/intel/qat/qat_common/adf_gen4_hw_data.c index f4a58f04071a..d9a0ed7eee3d 100644 --- a/drivers/crypto/intel/qat/qat_common/adf_gen4_hw_data.c +++ b/drivers/crypto/intel/qat/qat_common/adf_gen4_hw_data.c @@ -21,12 +21,6 @@ u32 adf_gen4_get_accel_mask(struct adf_hw_device_data *self) } EXPORT_SYMBOL_GPL(adf_gen4_get_accel_mask); -u32 adf_gen4_get_num_accels(struct adf_hw_device_data *self) -{ - return ADF_GEN4_MAX_ACCELERATORS; -} -EXPORT_SYMBOL_GPL(adf_gen4_get_num_accels); - u32 adf_gen4_get_num_aes(struct adf_hw_device_data *self) { if (!self || !self->ae_mask) diff --git a/drivers/crypto/intel/qat/qat_common/adf_gen4_hw_data.h b/drivers/crypto/intel/qat/qat_common/adf_gen4_hw_data.h index cd26b6724c43..46dfa23d825f 100644 --- a/drivers/crypto/intel/qat/qat_common/adf_gen4_hw_data.h +++ b/drivers/crypto/intel/qat/qat_common/adf_gen4_hw_data.h @@ -157,7 +157,6 @@ void adf_gen4_get_arb_info(struct arb_info *arb_info); u32 adf_gen4_get_etr_bar_id(struct adf_hw_device_data *self); u32 adf_gen4_get_heartbeat_clock(struct adf_hw_device_data *self); u32 adf_gen4_get_misc_bar_id(struct adf_hw_device_data *self); -u32 adf_gen4_get_num_accels(struct adf_hw_device_data *self); u32 adf_gen4_get_num_aes(struct adf_hw_device_data *self); enum dev_sku_info adf_gen4_get_sku(struct adf_hw_device_data *self); u32 adf_gen4_get_sram_bar_id(struct adf_hw_device_data *self); diff --git a/drivers/crypto/intel/qat/qat_common/adf_gen4_vf_mig.c b/drivers/crypto/intel/qat/qat_common/adf_gen4_vf_mig.c index bf2bae78a40d..d8b961b2f2f7 100644 --- a/drivers/crypto/intel/qat/qat_common/adf_gen4_vf_mig.c +++ b/drivers/crypto/intel/qat/qat_common/adf_gen4_vf_mig.c @@ -837,6 +837,9 @@ static int adf_gen4_vfmig_save_state(struct qat_mig_dev *mdev) return ret; } + memset(mdev->state + mdev->setup_size, 0, + mdev->state_size - mdev->setup_size); + adf_mstate_mgr_init(vfmig->mstate_mgr, mdev->state + mdev->setup_size, mdev->state_size - mdev->setup_size); if (!adf_mstate_preamble_add(vfmig->mstate_mgr)) @@ -934,6 +937,8 @@ static int adf_gen4_vfmig_save_setup(struct qat_mig_dev *mdev) if (mdev->setup_size) return 0; + memset(mdev->state, 0, mdev->state_size); + adf_mstate_mgr_init(vfmig->mstate_mgr, mdev->state, mdev->state_size); if (!adf_mstate_preamble_add(vfmig->mstate_mgr)) return -EINVAL; diff --git a/drivers/crypto/intel/qat/qat_common/adf_gen6_ras.c b/drivers/crypto/intel/qat/qat_common/adf_gen6_ras.c index 967253082a98..902c4b1a23e3 100644 --- a/drivers/crypto/intel/qat/qat_common/adf_gen6_ras.c +++ b/drivers/crypto/intel/qat/qat_common/adf_gen6_ras.c @@ -323,14 +323,26 @@ static void adf_handle_ti_cd_par_sts(struct adf_accel_dev *accel_dev, void __iom u32 ti_cd_par_sts; ti_cd_par_sts = ADF_CSR_RD(csr, ADF_GEN6_TI_CD_PAR_STS); - ti_cd_par_sts &= ADF_GEN6_TI_CD_PAR_STS_MASK; + ti_cd_par_sts &= ADF_GEN6_TI_CD_PAR_STS_TI_INT_ERR_DEVHALT_MASK; if (ti_cd_par_sts) { dev_err(&GET_DEV(accel_dev), "TI CD parity error: %#x\n", ti_cd_par_sts); - ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR); ADF_CSR_WR(csr, ADF_GEN6_TI_CD_PAR_STS, ti_cd_par_sts); } } +static void adf_handle_ti_misc_cd_par_sts(struct adf_accel_dev *accel_dev, void __iomem *csr) +{ + u32 ti_misc_cd_par_sts; + + ti_misc_cd_par_sts = ADF_CSR_RD(csr, ADF_GEN6_TI_CD_PAR_STS); + ti_misc_cd_par_sts &= ADF_GEN6_TI_CD_PAR_STS_TI_MISC_MASK; + if (ti_misc_cd_par_sts) { + dev_err(&GET_DEV(accel_dev), "TI MISC CD parity error: %#x\n", ti_misc_cd_par_sts); + ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR); + ADF_CSR_WR(csr, ADF_GEN6_TI_CD_PAR_STS, ti_misc_cd_par_sts); + } +} + static void adf_handle_ti_trnsb_par_sts(struct adf_accel_dev *accel_dev, void __iomem *csr) { u32 ti_trnsb_par_sts; @@ -367,7 +379,6 @@ static void adf_handle_ti_err(struct adf_accel_dev *accel_dev, void __iomem *csr adf_handle_ti_ci_par_sts(accel_dev, csr); adf_handle_ti_pullfub_par_sts(accel_dev, csr); adf_handle_ti_pushfub_par_sts(accel_dev, csr); - adf_handle_ti_cd_par_sts(accel_dev, csr); adf_handle_ti_trnsb_par_sts(accel_dev, csr); adf_handle_iosfp_cmd_parerr(accel_dev, csr); } @@ -591,6 +602,8 @@ static void adf_handle_timiscsts(struct adf_accel_dev *accel_dev, void __iomem * if (!(errsou & ADF_GEN6_ERRSOU3_TIMISCSTS_BIT)) return; + adf_handle_ti_misc_cd_par_sts(accel_dev, csr); + timiscsts = ADF_CSR_RD(csr, ADF_GEN6_TIMISCSTS); if (timiscsts) { dev_err(&GET_DEV(accel_dev), "Fatal error in transmit interface: %#x\n", @@ -730,6 +743,7 @@ static void adf_handle_ti_int_err_devhalt(struct adf_accel_dev *accel_dev, void if (!(errsou & ADF_GEN6_ERRSOU3_TI_INT_ERR_DEVHALT_BIT)) return; + adf_handle_ti_cd_par_sts(accel_dev, csr); dev_err(&GET_DEV(accel_dev), "DEVHALT due to a TI internal memory error\n"); ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_FATAL); } diff --git a/drivers/crypto/intel/qat/qat_common/adf_gen6_ras.h b/drivers/crypto/intel/qat/qat_common/adf_gen6_ras.h index 66ced271d173..11f7b2986f56 100644 --- a/drivers/crypto/intel/qat/qat_common/adf_gen6_ras.h +++ b/drivers/crypto/intel/qat/qat_common/adf_gen6_ras.h @@ -170,23 +170,25 @@ struct adf_ras_ops; #define ADF_GEN6_TI_CD_PAR_ERR_MASK 0x500638 /* - * TI CD parity status mask + * TI CD parity status mask - TI_INT_ERR_DEVHALT bits * BIT(0) - BIT(15) - CtxMdRam[0:15]_sts parity status * BIT(16) - Leaf2ClusterRam_sts parity status * BIT(17) - BIT(18) - Ring2LeafRam[0:1]_sts parity status - * BIT(19) - VirtualQ_sts parity status - * BIT(20) - DtRdQ_sts parity status - * BIT(21) - DtWrQ_sts parity status - * BIT(22) - RiCmdQ_sts parity status - * BIT(23) - BypassQ_sts parity status - * BIT(24) - DtRdQ_sc_sts parity status - * BIT(25) - DtWrQ_sc_sts parity status */ -#define ADF_GEN6_TI_CD_PAR_STS_MASK \ +#define ADF_GEN6_TI_CD_PAR_STS_TI_INT_ERR_DEVHALT_MASK \ (BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(6) | \ BIT(7) | BIT(8) | BIT(9) | BIT(10) | BIT(11) | BIT(12) | BIT(13) | \ - BIT(14) | BIT(15) | BIT(16) | BIT(17) | BIT(18) | BIT(19) | BIT(20) | \ - BIT(21) | BIT(22) | BIT(23) | BIT(24) | BIT(25)) + BIT(14) | BIT(15) | BIT(16) | BIT(17) | BIT(18)) + +/* + * TI CD parity status mask - TIMISCSTS bit + * BIT(19) - VirtualQ_sts parity status + */ +#define ADF_GEN6_TI_CD_PAR_STS_TI_MISC_MASK BIT(19) + +#define ADF_GEN6_TI_CD_PAR_STS_MASK \ + (ADF_GEN6_TI_CD_PAR_STS_TI_INT_ERR_DEVHALT_MASK | \ + ADF_GEN6_TI_CD_PAR_STS_TI_MISC_MASK) /* TI TRNSB parity status */ #define ADF_GEN6_TI_TRNSB_PAR_STS 0x500648 diff --git a/drivers/crypto/intel/qat/qat_common/adf_init.c b/drivers/crypto/intel/qat/qat_common/adf_init.c index 3e39c53814de..81cb5e6c9f4a 100644 --- a/drivers/crypto/intel/qat/qat_common/adf_init.c +++ b/drivers/crypto/intel/qat/qat_common/adf_init.c @@ -260,13 +260,23 @@ static int adf_dev_start(struct adf_accel_dev *accel_dev) clear_bit(ADF_STATUS_STARTING, &accel_dev->status); set_bit(ADF_STATUS_STARTED, &accel_dev->status); - if (!list_empty(&accel_dev->crypto_list) && - (qat_algs_register() || qat_asym_algs_register())) { - dev_err(&GET_DEV(accel_dev), - "Failed to register crypto algs\n"); - set_bit(ADF_STATUS_STARTING, &accel_dev->status); - clear_bit(ADF_STATUS_STARTED, &accel_dev->status); - return -EFAULT; + if (!list_empty(&accel_dev->crypto_list)) { + ret = qat_algs_register(); + if (ret) { + dev_err(&GET_DEV(accel_dev), "Failed to register crypto algs\n"); + set_bit(ADF_STATUS_STARTING, &accel_dev->status); + clear_bit(ADF_STATUS_STARTED, &accel_dev->status); + return ret; + } + + ret = qat_asym_algs_register(); + if (ret) { + dev_err(&GET_DEV(accel_dev), "Failed to register crypto asym algs\n"); + qat_algs_unregister(); + set_bit(ADF_STATUS_STARTING, &accel_dev->status); + clear_bit(ADF_STATUS_STARTED, &accel_dev->status); + return ret; + } } set_bit(ADF_STATUS_CRYPTO_ALGS_REGISTERED, &accel_dev->status); diff --git a/drivers/crypto/intel/qat/qat_common/adf_isr.c b/drivers/crypto/intel/qat/qat_common/adf_isr.c index 159e91a50106..0df4b398508e 100644 --- a/drivers/crypto/intel/qat/qat_common/adf_isr.c +++ b/drivers/crypto/intel/qat/qat_common/adf_isr.c @@ -70,6 +70,7 @@ void adf_enable_vf2pf_interrupts(struct adf_accel_dev *accel_dev, u32 vf_mask) void adf_enable_all_vf2pf_interrupts(struct adf_accel_dev *accel_dev, u32 num_vfs) { void __iomem *pmisc_addr = adf_get_pmisc_base(accel_dev); + struct adf_pfvf_ops *pfvf_ops = GET_PFVF_OPS(accel_dev); unsigned long flags; u32 vf_mask; @@ -79,7 +80,19 @@ void adf_enable_all_vf2pf_interrupts(struct adf_accel_dev *accel_dev, u32 num_vf spin_lock_irqsave(&accel_dev->pf.vf2pf_ints_lock, flags); WRITE_ONCE(accel_dev->pf.vf2pf_disabled, false); - GET_PFVF_OPS(accel_dev)->enable_vf2pf_interrupts(pmisc_addr, vf_mask); + /* + * A VF2PF interrupt is only generated when a source transitions from + * masked to unmasked. A VF may write to its VF2PF CSR while the source + * is masked or while the MSI-X vectors are torn down, for example + * during a device reset, leaving the source latched with no interrupt + * pending. The FLR performed as part of a device reset returns the mask + * register to its default value, which leaves all the sources unmasked, + * so simply unmasking is not guaranteed to be a transition. Mask all the + * sources first, so that unmasking always generates an interrupt for + * the sources latched in the meantime. + */ + pfvf_ops->disable_all_vf2pf_interrupts(pmisc_addr); + pfvf_ops->enable_vf2pf_interrupts(pmisc_addr, vf_mask); spin_unlock_irqrestore(&accel_dev->pf.vf2pf_ints_lock, flags); } diff --git a/drivers/crypto/intel/qat/qat_common/adf_sysfs_kpt.c b/drivers/crypto/intel/qat/qat_common/adf_sysfs_kpt.c index 1f733ae80bdf..a0db98f33f1f 100644 --- a/drivers/crypto/intel/qat/qat_common/adf_sysfs_kpt.c +++ b/drivers/crypto/intel/qat/qat_common/adf_sysfs_kpt.c @@ -31,6 +31,7 @@ static ssize_t enable_store(struct device *dev, struct device_attribute *attr, struct adf_hw_device_data *hw_data; struct adf_accel_dev *accel_dev; bool enable; + int svc; int ret; accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev)); @@ -38,14 +39,25 @@ static ssize_t enable_store(struct device *dev, struct device_attribute *attr, return -EINVAL; if (adf_dev_started(accel_dev)) { - dev_info(dev, "Device qat_dev%d must be down before enabling KPT\n", + dev_info(dev, "Device qat_dev%d must be down before changing KPT state\n", accel_dev->accel_id); return -EINVAL; } - if (adf_get_service_enabled(accel_dev) != SVC_ASYM) { - dev_info(dev, "KPT can only be enabled when the asymmetric service is enabled\n"); - return -EINVAL; + ret = kstrtobool(buf, &enable); + if (ret) + return ret; + + if (enable) { + svc = adf_get_service_enabled(accel_dev); + if (svc < 0) + return svc; + + if (svc != SVC_ASYM) { + dev_info(dev, + "KPT can only be enabled when the asymmetric crypto service is enabled\n"); + return -EINVAL; + } } hw_data = GET_HW_DATA(accel_dev); @@ -59,10 +71,6 @@ static ssize_t enable_store(struct device *dev, struct device_attribute *attr, if (!hw_data->accel_capabilities_mask) return -EINVAL; - ret = kstrtobool(buf, &enable); - if (ret) - return ret; - user_data = GET_KPT_USER_DATA(accel_dev); user_data->enable = enable; diff --git a/drivers/crypto/intel/qat/qat_common/adf_vf_isr.c b/drivers/crypto/intel/qat/qat_common/adf_vf_isr.c index 9ffaa56def67..1f28655ec051 100644 --- a/drivers/crypto/intel/qat/qat_common/adf_vf_isr.c +++ b/drivers/crypto/intel/qat/qat_common/adf_vf_isr.c @@ -118,7 +118,6 @@ static int adf_setup_pf2vf_bh(struct adf_accel_dev *accel_dev) tasklet_init(&accel_dev->vf.pf2vf_bh_tasklet, (void *)adf_pf2vf_bh_handler, (unsigned long)accel_dev); - mutex_init(&accel_dev->vf.vf2pf_lock); return 0; } @@ -126,7 +125,6 @@ static void adf_cleanup_pf2vf_bh(struct adf_accel_dev *accel_dev) { tasklet_disable(&accel_dev->vf.pf2vf_bh_tasklet); tasklet_kill(&accel_dev->vf.pf2vf_bh_tasklet); - mutex_destroy(&accel_dev->vf.vf2pf_lock); } static irqreturn_t adf_isr(int irq, void *privdata) diff --git a/drivers/crypto/intel/qat/qat_common/qat_algs.c b/drivers/crypto/intel/qat/qat_common/qat_algs.c index 91663805d9e6..2ec19104787f 100644 --- a/drivers/crypto/intel/qat/qat_common/qat_algs.c +++ b/drivers/crypto/intel/qat/qat_common/qat_algs.c @@ -388,7 +388,7 @@ static void qat_alg_skcipher_init_enc(struct qat_alg_skcipher_ctx *ctx, static void qat_alg_xts_reverse_key(const u8 *key_forward, unsigned int keylen, u8 *key_reverse) { - struct crypto_aes_ctx aes_expanded; + struct crypto_aes_ctx aes_expanded __cleanup(aes_zeroize_ctx); int nrounds; u8 *key; @@ -405,7 +405,6 @@ static void qat_alg_xts_reverse_key(const u8 *key_forward, unsigned int keylen, memcpy(key_reverse + AES_BLOCK_SIZE, key - AES_BLOCK_SIZE, AES_BLOCK_SIZE); } - memzero_explicit(&aes_expanded, sizeof(aes_expanded)); } static void qat_alg_skcipher_init_dec(struct qat_alg_skcipher_ctx *ctx, @@ -1320,19 +1319,22 @@ int qat_algs_register(void) ret = crypto_register_skciphers(qat_skciphers, ARRAY_SIZE(qat_skciphers)); if (ret) - goto unlock; + goto err_dec; ret = crypto_register_aeads(qat_aeads, ARRAY_SIZE(qat_aeads)); if (ret) - goto unreg_algs; + goto err_unreg_skciphers; -unlock: mutex_unlock(&algs_lock); - return ret; + return 0; -unreg_algs: +err_unreg_skciphers: crypto_unregister_skciphers(qat_skciphers, ARRAY_SIZE(qat_skciphers)); - goto unlock; +err_dec: + active_devs--; +unlock: + mutex_unlock(&algs_lock); + return ret; } void qat_algs_unregister(void) diff --git a/drivers/crypto/intel/qat/qat_common/qat_asym_algs.c b/drivers/crypto/intel/qat/qat_common/qat_asym_algs.c index 75c15c8e41db..77d59e977472 100644 --- a/drivers/crypto/intel/qat/qat_common/qat_asym_algs.c +++ b/drivers/crypto/intel/qat/qat_common/qat_asym_algs.c @@ -535,8 +535,10 @@ static int qat_dh_init_tfm(struct crypto_kpp *tfm) return -EINVAL; ctx->ftfm = crypto_alloc_kpp(alg, 0, CRYPTO_ALG_NEED_FALLBACK); - if (IS_ERR(ctx->ftfm)) + if (IS_ERR(ctx->ftfm)) { + qat_crypto_put_instance(inst); return PTR_ERR(ctx->ftfm); + } crypto_kpp_set_flags(ctx->ftfm, crypto_kpp_get_flags(tfm)); @@ -987,7 +989,7 @@ static int qat_rsa_set_n(struct qat_rsa_ctx *ctx, const char *value, const char *ptr = value; int ret; - while (!*ptr && vlen) { + while (vlen && !*ptr) { ptr++; vlen--; } @@ -1018,7 +1020,7 @@ static int qat_rsa_set_e(struct qat_rsa_ctx *ctx, const char *value, struct device *dev = &GET_DEV(inst->accel_dev); const char *ptr = value; - while (!*ptr && vlen) { + while (vlen && !*ptr) { ptr++; vlen--; } @@ -1044,7 +1046,7 @@ static int qat_rsa_set_d(struct qat_rsa_ctx *ctx, const char *value, const char *ptr = value; int ret; - while (!*ptr && vlen) { + while (vlen && !*ptr) { ptr++; vlen--; } @@ -1067,7 +1069,7 @@ err: static void qat_rsa_drop_leading_zeros(const char **ptr, unsigned int *len) { - while (!**ptr && *len) { + while (*len && !**ptr) { (*ptr)++; (*len)--; } @@ -1338,13 +1340,25 @@ int qat_asym_algs_register(void) int ret = 0; mutex_lock(&algs_lock); - if (++active_devs == 1) { - rsa.base.cra_flags = 0; - ret = crypto_register_akcipher(&rsa); - if (ret) - goto unlock; - ret = crypto_register_kpp(&dh); - } + if (++active_devs != 1) + goto unlock; + + rsa.base.cra_flags = 0; + ret = crypto_register_akcipher(&rsa); + if (ret) + goto err_dec; + + ret = crypto_register_kpp(&dh); + if (ret) + goto err_unreg_akcipher; + + mutex_unlock(&algs_lock); + return 0; + +err_unreg_akcipher: + crypto_unregister_akcipher(&rsa); +err_dec: + active_devs--; unlock: mutex_unlock(&algs_lock); return ret; diff --git a/drivers/crypto/intel/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c b/drivers/crypto/intel/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c index 5b4bd0ba1ccb..c318015fc2e2 100644 --- a/drivers/crypto/intel/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c +++ b/drivers/crypto/intel/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c @@ -229,7 +229,6 @@ void adf_init_hw_data_dh895xcc(struct adf_hw_device_data *hw_data) hw_data->get_accel_mask = get_accel_mask; hw_data->get_ae_mask = get_ae_mask; hw_data->get_accel_cap = get_accel_cap; - hw_data->get_num_accels = adf_gen2_get_num_accels; hw_data->get_num_aes = adf_gen2_get_num_aes; hw_data->get_etr_bar_id = get_etr_bar_id; hw_data->get_misc_bar_id = get_misc_bar_id; diff --git a/drivers/crypto/intel/qat/qat_dh895xccvf/adf_dh895xccvf_hw_data.c b/drivers/crypto/intel/qat/qat_dh895xccvf/adf_dh895xccvf_hw_data.c index 828456c43b76..6fd5bb333859 100644 --- a/drivers/crypto/intel/qat/qat_dh895xccvf/adf_dh895xccvf_hw_data.c +++ b/drivers/crypto/intel/qat/qat_dh895xccvf/adf_dh895xccvf_hw_data.c @@ -24,11 +24,6 @@ static u32 get_ae_mask(struct adf_hw_device_data *self) return ADF_DH895XCCIOV_ACCELENGINES_MASK; } -static u32 get_num_accels(struct adf_hw_device_data *self) -{ - return ADF_DH895XCCIOV_MAX_ACCELERATORS; -} - static u32 get_num_aes(struct adf_hw_device_data *self) { return ADF_DH895XCCIOV_MAX_ACCELENGINES; @@ -80,7 +75,6 @@ void adf_init_hw_data_dh895xcciov(struct adf_hw_device_data *hw_data) hw_data->disable_iov = adf_vf2pf_notify_shutdown; hw_data->get_accel_mask = get_accel_mask; hw_data->get_ae_mask = get_ae_mask; - hw_data->get_num_accels = get_num_accels; hw_data->get_num_aes = get_num_aes; hw_data->get_etr_bar_id = get_etr_bar_id; hw_data->get_misc_bar_id = get_misc_bar_id; diff --git a/drivers/crypto/marvell/octeontx/otx_cptvf_algs.c b/drivers/crypto/marvell/octeontx/otx_cptvf_algs.c index 096be42e9d03..2f088afc536d 100644 --- a/drivers/crypto/marvell/octeontx/otx_cptvf_algs.c +++ b/drivers/crypto/marvell/octeontx/otx_cptvf_algs.c @@ -16,6 +16,7 @@ #include <crypto/sha1.h> #include <crypto/sha2.h> #include <crypto/xts.h> +#include <crypto/utils.h> #include <crypto/scatterwalk.h> #include <linux/sort.h> #include <linux/module.h> @@ -105,9 +106,9 @@ static inline int validate_hmac_cipher_null(struct otx_cpt_req_info *cpt_req) req = container_of(cpt_req->areq, struct aead_request, base); tfm = crypto_aead_reqtfm(req); rctx = aead_request_ctx_dma(req); - if (memcmp(rctx->fctx.hmac.s.hmac_calc, - rctx->fctx.hmac.s.hmac_recv, - crypto_aead_authsize(tfm)) != 0) + if (crypto_memneq(rctx->fctx.hmac.s.hmac_calc, + rctx->fctx.hmac.s.hmac_recv, + crypto_aead_authsize(tfm))) return -EBADMSG; return 0; @@ -792,8 +793,7 @@ static int aead_hmac_init(struct crypto_aead *cipher, ipad = ctx->ipad; opad = ctx->opad; - memcpy(ipad, ctx->key, authkeylen); - memset(ipad + authkeylen, 0, bs - authkeylen); + memcpy_and_pad(ipad, bs, ctx->key, authkeylen, 0); memcpy(opad, ipad, bs); for (icount = 0; icount < bs; icount++) { diff --git a/drivers/crypto/marvell/octeontx/otx_cptvf_mbox.c b/drivers/crypto/marvell/octeontx/otx_cptvf_mbox.c index 90fdafb7c468..38d1de24652b 100644 --- a/drivers/crypto/marvell/octeontx/otx_cptvf_mbox.c +++ b/drivers/crypto/marvell/octeontx/otx_cptvf_mbox.c @@ -180,7 +180,7 @@ int otx_cptvf_send_vq_size_msg(struct otx_cptvf *cptvf) } /* - * Communicate VF group required to PF and get the VQ binded to that group + * Communicate VF group required to PF and get the VQ bound to that group */ int otx_cptvf_send_vf_to_grp_msg(struct otx_cptvf *cptvf, int group) { @@ -199,7 +199,7 @@ int otx_cptvf_send_vf_to_grp_msg(struct otx_cptvf *cptvf, int group) } /* - * Communicate VF group required to PF and get the VQ binded to that group + * Communicate VF group required to PF and get the VQ bound to that group */ int otx_cptvf_send_vf_priority_msg(struct otx_cptvf *cptvf) { diff --git a/drivers/crypto/marvell/octeontx2/otx2_cptvf_algs.c b/drivers/crypto/marvell/octeontx2/otx2_cptvf_algs.c index 8d9f394d6b50..9eb5dc0a4da6 100644 --- a/drivers/crypto/marvell/octeontx2/otx2_cptvf_algs.c +++ b/drivers/crypto/marvell/octeontx2/otx2_cptvf_algs.c @@ -11,6 +11,7 @@ #include <crypto/xts.h> #include <crypto/gcm.h> #include <crypto/scatterwalk.h> +#include <crypto/utils.h> #include <linux/sort.h> #include <linux/module.h> #include "otx2_cptvf.h" @@ -90,9 +91,9 @@ static inline int validate_hmac_cipher_null(struct otx2_cpt_req_info *cpt_req) req = container_of(cpt_req->areq, struct aead_request, base); tfm = crypto_aead_reqtfm(req); rctx = aead_request_ctx_dma(req); - if (memcmp(rctx->fctx.hmac.s.hmac_calc, - rctx->fctx.hmac.s.hmac_recv, - crypto_aead_authsize(tfm)) != 0) + if (crypto_memneq(rctx->fctx.hmac.s.hmac_calc, + rctx->fctx.hmac.s.hmac_recv, + crypto_aead_authsize(tfm))) return -EBADMSG; return 0; @@ -882,8 +883,7 @@ static int aead_hmac_init(struct crypto_aead *cipher, ipad = ctx->ipad; opad = ctx->opad; - memcpy(ipad, ctx->key, authkeylen); - memset(ipad + authkeylen, 0, bs - authkeylen); + memcpy_and_pad(ipad, bs, ctx->key, authkeylen, 0); memcpy(opad, ipad, bs); for (icount = 0; icount < bs; icount++) { diff --git a/drivers/crypto/mxs-dcp.c b/drivers/crypto/mxs-dcp.c index c75a06999787..d104d958cb61 100644 --- a/drivers/crypto/mxs-dcp.c +++ b/drivers/crypto/mxs-dcp.c @@ -473,6 +473,9 @@ static int mxs_dcp_aes_enqueue(struct skcipher_request *req, int enc, int ecb) struct dcp_aes_req_ctx *rctx = skcipher_request_ctx(req); int ret; + if (!req->cryptlen) + return 0; + if (unlikely(actx->key_len != AES_KEYSIZE_128 && !actx->key_referenced)) return mxs_dcp_block_fallback(req, enc); diff --git a/drivers/crypto/nx/nx-842.c b/drivers/crypto/nx/nx-842.c index a61208cbcd27..b4404a138962 100644 --- a/drivers/crypto/nx/nx-842.c +++ b/drivers/crypto/nx/nx-842.c @@ -421,6 +421,8 @@ usesw: slen -= spadding; + if (ignore > dlen) + return -EINVAL; dlen -= ignore; if (ignore) pr_debug("ignoring last %x bytes\n", ignore); diff --git a/drivers/crypto/omap-des.c b/drivers/crypto/omap-des.c index 3b7104cb4487..4b5a8d13f505 100644 --- a/drivers/crypto/omap-des.c +++ b/drivers/crypto/omap-des.c @@ -1082,6 +1082,8 @@ static void omap_des_remove(struct platform_device *pdev) omap_des_unregister_algs(dd->pdata); + crypto_engine_exit(dd->engine); + cancel_work_sync(&dd->done_task); omap_des_dma_cleanup(dd); pm_runtime_disable(dd->dev); diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c index 6d2dd0b88f15..5e739415a010 100644 --- a/drivers/crypto/omap-sham.c +++ b/drivers/crypto/omap-sham.c @@ -1265,7 +1265,7 @@ static int omap_sham_finup(struct ahash_request *req) return err1; /* * final() has to be always called to cleanup resources - * even if udpate() failed, except EINPROGRESS + * even if update() failed, except EINPROGRESS */ err2 = omap_sham_final(req); @@ -1732,7 +1732,7 @@ static void omap_sham_done_task(struct work_struct *t) finish: dev_dbg(dd->dev, "update done: err: %d\n", err); - /* finish curent request */ + /* finish current request */ omap_sham_finish_req(dd->req, err); } @@ -2129,6 +2129,7 @@ static void omap_sham_remove(struct platform_device *pdev) list_del(&dd->list); spin_unlock_bh(&sham.lock); omap_sham_unregister_algs(dd->pdata); + crypto_engine_exit(dd->engine); cancel_work_sync(&dd->done_task); pm_runtime_dont_use_autosuspend(&pdev->dev); pm_runtime_disable(&pdev->dev); diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c index 1be549a07a21..400a889e924d 100644 --- a/drivers/crypto/padlock-aes.c +++ b/drivers/crypto/padlock-aes.c @@ -109,7 +109,7 @@ static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, { struct aes_ctx *ctx = aes_ctx(tfm); const __le32 *key = (const __le32 *)in_key; - struct crypto_aes_ctx gen_aes; + struct crypto_aes_ctx gen_aes __cleanup(aes_zeroize_ctx); int cpu; if (key_len % 8) @@ -137,20 +137,18 @@ static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, ctx->cword.decrypt.ksize = ctx->cword.encrypt.ksize; /* Don't generate extended keys if the hardware can do it. */ - if (aes_hw_extkey_available(key_len)) - goto ok; + if (!aes_hw_extkey_available(key_len)) { + ctx->D = ctx->d_data; + ctx->cword.encrypt.keygen = 1; + ctx->cword.decrypt.keygen = 1; - ctx->D = ctx->d_data; - ctx->cword.encrypt.keygen = 1; - ctx->cword.decrypt.keygen = 1; + if (aes_expandkey(&gen_aes, in_key, key_len)) + return -EINVAL; - if (aes_expandkey(&gen_aes, in_key, key_len)) - return -EINVAL; - - memcpy(ctx->E, gen_aes.key_enc, AES_MAX_KEYLENGTH); - memcpy(ctx->D, gen_aes.key_dec, AES_MAX_KEYLENGTH); + memcpy(ctx->E, gen_aes.key_enc, AES_MAX_KEYLENGTH); + memcpy(ctx->D, gen_aes.key_dec, AES_MAX_KEYLENGTH); + } -ok: for_each_online_cpu(cpu) if (&ctx->cword.encrypt == per_cpu(paes_last_cword, cpu) || &ctx->cword.decrypt == per_cpu(paes_last_cword, cpu)) diff --git a/drivers/crypto/qce/aead.c b/drivers/crypto/qce/aead.c index a9642c67f476..e0061bfab216 100644 --- a/drivers/crypto/qce/aead.c +++ b/drivers/crypto/qce/aead.c @@ -379,7 +379,7 @@ static int qce_aead_create_ccm_nonce(struct qce_aead_reqctx *rctx, struct qce_ae /* * The crypto framework encodes cryptlen as unsigned int. Thus, even though - * spec allows for upto 8 bytes to encode msg_len only 4 bytes are needed. + * spec allows for up to 8 bytes to encode msg_len only 4 bytes are needed. */ if (msglen_size > 4) msglen_size = 4; @@ -769,14 +769,13 @@ static int qce_aead_register(struct qce_device *qce) for (i = 0; i < ARRAY_SIZE(aead_def); i++) { ret = qce_aead_register_one(&aead_def[i], qce); - if (ret) - goto err; + if (ret) { + qce_aead_unregister(qce); + return ret; + } } return 0; -err: - qce_aead_unregister(qce); - return ret; } const struct qce_algo_ops aead_ops = { diff --git a/drivers/crypto/qce/sha.c b/drivers/crypto/qce/sha.c index eb8a5b0c4173..b67d749db05f 100644 --- a/drivers/crypto/qce/sha.c +++ b/drivers/crypto/qce/sha.c @@ -480,14 +480,13 @@ static int qce_ahash_register(struct qce_device *qce) for (i = 0; i < ARRAY_SIZE(ahash_def); i++) { ret = qce_ahash_register_one(&ahash_def[i], qce); - if (ret) - goto err; + if (ret) { + qce_ahash_unregister(qce); + return ret; + } } return 0; -err: - qce_ahash_unregister(qce); - return ret; } const struct qce_algo_ops ahash_ops = { diff --git a/drivers/crypto/qce/skcipher.c b/drivers/crypto/qce/skcipher.c index 4931b064f10e..03a3cec2bb90 100644 --- a/drivers/crypto/qce/skcipher.c +++ b/drivers/crypto/qce/skcipher.c @@ -416,14 +416,13 @@ static int qce_skcipher_register(struct qce_device *qce) for (i = 0; i < ARRAY_SIZE(skcipher_def); i++) { ret = qce_skcipher_register_one(&skcipher_def[i], qce); - if (ret) - goto err; + if (ret) { + qce_skcipher_unregister(qce); + return ret; + } } return 0; -err: - qce_skcipher_unregister(qce); - return ret; } const struct qce_algo_ops skcipher_ops = { diff --git a/drivers/crypto/rockchip/rk3288_crypto.c b/drivers/crypto/rockchip/rk3288_crypto.c index 7cb1316b6f18..b2b629fffc05 100644 --- a/drivers/crypto/rockchip/rk3288_crypto.c +++ b/drivers/crypto/rockchip/rk3288_crypto.c @@ -163,7 +163,7 @@ static void rk_crypto_pm_exit(struct rk_crypto_info *rkdev) static irqreturn_t rk_crypto_irq_handle(int irq, void *dev_id) { - struct rk_crypto_info *dev = platform_get_drvdata(dev_id); + struct rk_crypto_info *dev = dev_id; u32 interrupt_status; interrupt_status = CRYPTO_READ(dev, RK_CRYPTO_INTSTS); @@ -363,7 +363,7 @@ static int rk_crypto_probe(struct platform_device *pdev) err = devm_request_irq(&pdev->dev, crypto_info->irq, rk_crypto_irq_handle, IRQF_SHARED, - "rk-crypto", pdev); + "rk-crypto", crypto_info); if (err) goto err_crypto; diff --git a/drivers/crypto/s5p-sss.c b/drivers/crypto/s5p-sss.c index bdda7b39af85..a70102799223 100644 --- a/drivers/crypto/s5p-sss.c +++ b/drivers/crypto/s5p-sss.c @@ -638,8 +638,7 @@ static int s5p_hash_rx(struct s5p_aes_dev *dev) static irqreturn_t s5p_aes_interrupt(int irq, void *dev_id) { - struct platform_device *pdev = dev_id; - struct s5p_aes_dev *dev = platform_get_drvdata(pdev); + struct s5p_aes_dev *dev = dev_id; struct skcipher_request *req; int err_dma_tx = 0; int err_dma_rx = 0; @@ -1446,7 +1445,7 @@ static void s5p_hash_tasklet_cb(unsigned long data) return; finish: - /* finish curent request */ + /* finish current request */ s5p_hash_finish_req(dd->hash_req, 0); /* If we are not busy, process next req */ @@ -2221,7 +2220,7 @@ static int s5p_aes_probe(struct platform_device *pdev) } err = devm_request_threaded_irq(dev, pdata->irq_fc, NULL, s5p_aes_interrupt, IRQF_ONESHOT, - pdev->name, pdev); + pdev->name, pdata); if (err < 0) { dev_warn(dev, "feed control interrupt is not available.\n"); goto err_irq; diff --git a/drivers/crypto/sa2ul.c b/drivers/crypto/sa2ul.c index 9846cbeb3449..4557eae94164 100644 --- a/drivers/crypto/sa2ul.c +++ b/drivers/crypto/sa2ul.c @@ -125,9 +125,7 @@ struct sa_cmdl_cfg { * @mci_enc: Mode Control Instruction for Encryption algorithm * @mci_dec: Mode Control Instruction for Decryption * @inv_key: Whether the encryption algorithm demands key inversion - * @ctx: Pointer to the algorithm context * @keyed_mac: Whether the authentication algorithm has key - * @prep_iopad: Function pointer to generate intermediate ipad/opad */ struct algo_data { struct sa_eng_info enc_eng; @@ -141,10 +139,7 @@ struct algo_data { u8 *mci_enc; u8 *mci_dec; bool inv_key; - struct sa_tfm_ctx *ctx; bool keyed_mac; - void (*prep_iopad)(struct algo_data *algo, const u8 *key, - u16 key_sz, __be32 *ipad, __be32 *opad); }; /** @@ -381,92 +376,42 @@ static void sa_swiz_128(u8 *in, u16 len) } } -/* Prepare the ipad and opad from key as per SHA algorithm step 1*/ -static void prepare_kipad(u8 *k_ipad, const u8 *key, u16 key_sz) +static void sa_prepare_iopads(struct algo_data *data, const u8 *key, u16 key_sz, + __be32 *ipad, __be32 *opad) { - int i; - - for (i = 0; i < key_sz; i++) - k_ipad[i] = key[i] ^ 0x36; - - /* Instead of XOR with 0 */ - for (; i < SHA1_BLOCK_SIZE; i++) - k_ipad[i] = 0x36; -} - -static void prepare_kopad(u8 *k_opad, const u8 *key, u16 key_sz) -{ - int i; - - for (i = 0; i < key_sz; i++) - k_opad[i] = key[i] ^ 0x5c; - - /* Instead of XOR with 0 */ - for (; i < SHA1_BLOCK_SIZE; i++) - k_opad[i] = 0x5c; -} - -static void sa_export_shash(void *state, struct shash_desc *hash, - int digest_size, __be32 *out) -{ - struct sha1_state *sha1; - struct sha256_state *sha256; - u32 *result; - - switch (digest_size) { - case SHA1_DIGEST_SIZE: - sha1 = state; - result = sha1->state; + union { + struct hmac_sha1_key sha1; + struct hmac_sha256_key sha256; + } k; + + switch (data->aalg_id) { + case SA_AALG_ID_HMAC_SHA1: + hmac_sha1_preparekey(&k.sha1, key, key_sz); + cpu_to_be32_array(ipad, k.sha1.istate.h, + ARRAY_SIZE(k.sha1.istate.h)); + cpu_to_be32_array(opad, k.sha1.ostate.h, + ARRAY_SIZE(k.sha1.ostate.h)); break; - case SHA256_DIGEST_SIZE: - sha256 = state; - result = sha256->state; + case SA_AALG_ID_HMAC_SHA2_256: + hmac_sha256_preparekey(&k.sha256, key, key_sz); + cpu_to_be32_array(ipad, k.sha256.key.istate.h, + ARRAY_SIZE(k.sha256.key.istate.h)); + cpu_to_be32_array(opad, k.sha256.key.ostate.h, + ARRAY_SIZE(k.sha256.key.ostate.h)); break; default: - dev_err(sa_k3_dev, "%s: bad digest_size=%d\n", __func__, - digest_size); + dev_err(sa_k3_dev, "%s: bad aalg_id=%d\n", __func__, + data->aalg_id); return; } - crypto_shash_export(hash, state); - - cpu_to_be32_array(out, result, digest_size / 4); -} - -static void sa_prepare_iopads(struct algo_data *data, const u8 *key, - u16 key_sz, __be32 *ipad, __be32 *opad) -{ - SHASH_DESC_ON_STACK(shash, data->ctx->shash); - int block_size = crypto_shash_blocksize(data->ctx->shash); - int digest_size = crypto_shash_digestsize(data->ctx->shash); - union { - struct sha1_state sha1; - struct sha256_state sha256; - u8 k_pad[SHA1_BLOCK_SIZE]; - } sha; - - shash->tfm = data->ctx->shash; - - prepare_kipad(sha.k_pad, key, key_sz); - - crypto_shash_init(shash); - crypto_shash_update(shash, sha.k_pad, block_size); - sa_export_shash(&sha, shash, digest_size, ipad); - - prepare_kopad(sha.k_pad, key, key_sz); - - crypto_shash_init(shash); - crypto_shash_update(shash, sha.k_pad, block_size); - - sa_export_shash(&sha, shash, digest_size, opad); - - memzero_explicit(&sha, sizeof(sha)); + memzero_explicit(&k, sizeof(k)); } /* Derive the inverse key used in AES-CBC decryption operation */ static inline int sa_aes_inv_key(u8 *inv_key, const u8 *key, u16 key_sz) { - struct crypto_aes_ctx ctx; + struct crypto_aes_ctx ctx __cleanup(aes_zeroize_ctx); int key_pos; if (aes_expandkey(&ctx, key, key_sz)) { @@ -544,7 +489,7 @@ static void sa_set_sc_auth(struct algo_data *ad, const u8 *key, u16 key_sz, /* Copy the keys or ipad/opad */ if (ad->keyed_mac) - ad->prep_iopad(ad, key, key_sz, ipad, opad); + sa_prepare_iopads(ad, key, key_sz, ipad, opad); else { /* basic hash */ sc_buf[1] |= SA_BASIC_HASH; @@ -1443,7 +1388,6 @@ static int sa_sha_run(struct ahash_request *req) static int sa_sha_setup(struct sa_tfm_ctx *ctx, struct algo_data *ad) { - int bs = crypto_shash_blocksize(ctx->shash); int cmdl_len; struct sa_cmdl_cfg cfg; @@ -1451,7 +1395,6 @@ static int sa_sha_setup(struct sa_tfm_ctx *ctx, struct algo_data *ad) ad->auth_eng.eng_id = SA_ENG_ID_AM1; ad->auth_eng.sc_size = SA_CTX_AUTH_TYPE2_SZ; - memset(ctx->authkey, 0, bs); memset(&cfg, 0, sizeof(cfg)); cfg.aalg = ad->aalg_id; cfg.enc_eng_id = ad->enc_eng.eng_id; @@ -1494,12 +1437,6 @@ static int sa_sha_cra_init_alg(struct crypto_tfm *tfm, const char *alg_base) return ret; if (alg_base) { - ctx->shash = crypto_alloc_shash(alg_base, 0, 0); - if (IS_ERR(ctx->shash)) { - dev_err(sa_k3_dev, "base driver %s couldn't be loaded\n", - alg_base); - return PTR_ERR(ctx->shash); - } /* for fallback */ ctx->fallback.ahash = crypto_alloc_ahash(alg_base, 0, CRYPTO_ALG_ASYNC); @@ -1654,7 +1591,6 @@ static void sa_sha_cra_exit(struct crypto_tfm *tfm) if (crypto_tfm_alg_type(tfm) == CRYPTO_ALG_TYPE_AHASH) sa_free_ctx_info(&ctx->enc, data); - crypto_free_shash(ctx->shash); crypto_free_ahash(ctx->fallback.ahash); } @@ -1697,8 +1633,7 @@ static void sa_aead_dma_in_callback(void *data) aead_request_complete(req, err); } -static int sa_cra_init_aead(struct crypto_aead *tfm, const char *hash, - const char *fallback) +static int sa_cra_init_aead(struct crypto_aead *tfm, const char *fallback) { struct sa_tfm_ctx *ctx = crypto_aead_ctx(tfm); struct sa_crypto_data *data = dev_get_drvdata(sa_k3_dev); @@ -1707,12 +1642,6 @@ static int sa_cra_init_aead(struct crypto_aead *tfm, const char *hash, memzero_explicit(ctx, sizeof(*ctx)); ctx->dev_data = data; - ctx->shash = crypto_alloc_shash(hash, 0, CRYPTO_ALG_NEED_FALLBACK); - if (IS_ERR(ctx->shash)) { - dev_err(sa_k3_dev, "base driver %s couldn't be loaded\n", hash); - return PTR_ERR(ctx->shash); - } - ctx->fallback.aead = crypto_alloc_aead(fallback, 0, CRYPTO_ALG_NEED_FALLBACK); @@ -1744,14 +1673,12 @@ static int sa_cra_init_aead(struct crypto_aead *tfm, const char *hash, static int sa_cra_init_aead_sha1(struct crypto_aead *tfm) { - return sa_cra_init_aead(tfm, "sha1", - "authenc(hmac(sha1),cbc(aes))"); + return sa_cra_init_aead(tfm, "authenc(hmac(sha1),cbc(aes))"); } static int sa_cra_init_aead_sha256(struct crypto_aead *tfm) { - return sa_cra_init_aead(tfm, "sha256", - "authenc(hmac(sha256),cbc(aes))"); + return sa_cra_init_aead(tfm, "authenc(hmac(sha256),cbc(aes))"); } static void sa_exit_tfm_aead(struct crypto_aead *tfm) @@ -1759,7 +1686,6 @@ static void sa_exit_tfm_aead(struct crypto_aead *tfm) struct sa_tfm_ctx *ctx = crypto_aead_ctx(tfm); struct sa_crypto_data *data = dev_get_drvdata(sa_k3_dev); - crypto_free_shash(ctx->shash); crypto_free_aead(ctx->fallback.aead); sa_free_ctx_info(&ctx->enc, data); @@ -1785,7 +1711,6 @@ static int sa_aead_setkey(struct crypto_aead *authenc, if (key_idx >= 3) return -EINVAL; - ad->ctx = ctx; ad->enc_eng.eng_id = SA_ENG_ID_EM1; ad->enc_eng.sc_size = SA_CTX_ENC_TYPE1_SZ; ad->auth_eng.eng_id = SA_ENG_ID_AM1; @@ -1795,7 +1720,6 @@ static int sa_aead_setkey(struct crypto_aead *authenc, ad->inv_key = true; ad->keyed_mac = true; ad->ealg_id = SA_EALG_ID_AES_CBC; - ad->prep_iopad = sa_prepare_iopads; memset(&cfg, 0, sizeof(cfg)); cfg.enc = true; diff --git a/drivers/crypto/sa2ul.h b/drivers/crypto/sa2ul.h index 12c17a68d350..211ef4e40f22 100644 --- a/drivers/crypto/sa2ul.h +++ b/drivers/crypto/sa2ul.h @@ -307,12 +307,9 @@ struct sa_tfm_ctx { struct sa_crypto_data *dev_data; struct sa_ctx_info enc; struct sa_ctx_info dec; - struct sa_ctx_info auth; int keylen; int iv_idx; u32 key[AES_KEYSIZE_256 / sizeof(u32)]; - u8 authkey[SHA512_BLOCK_SIZE]; - struct crypto_shash *shash; /* for fallback */ union { struct crypto_skcipher *skcipher; diff --git a/drivers/crypto/starfive/jh7110-cryp.c b/drivers/crypto/starfive/jh7110-cryp.c index 842f76b0f114..856290347b95 100644 --- a/drivers/crypto/starfive/jh7110-cryp.c +++ b/drivers/crypto/starfive/jh7110-cryp.c @@ -120,9 +120,17 @@ 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"); - clk_prepare_enable(cryp->hclk); - clk_prepare_enable(cryp->ahb); - reset_control_deassert(cryp->rst); + ret = clk_prepare_enable(cryp->hclk); + if (ret) + return ret; + + ret = clk_prepare_enable(cryp->ahb); + if (ret) + goto disable_hclk; + + ret = reset_control_deassert(cryp->rst); + if (ret) + goto disable_ahb; spin_lock(&dev_list.lock); list_add(&cryp->list, &dev_list.dev_list); @@ -170,9 +178,11 @@ err_dma_init: list_del(&cryp->list); spin_unlock(&dev_list.lock); - clk_disable_unprepare(cryp->hclk); - clk_disable_unprepare(cryp->ahb); reset_control_assert(cryp->rst); +disable_ahb: + clk_disable_unprepare(cryp->ahb); +disable_hclk: + clk_disable_unprepare(cryp->hclk); return ret; } diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index fa96b6bf17e3..c7d9ce2905be 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c @@ -751,8 +751,7 @@ static void talitos_error(struct device *dev, u32 isr, u32 isr_lo) #define DEF_TALITOS1_INTERRUPT(name, ch_done_mask, ch_err_mask, tlet) \ static irqreturn_t talitos1_interrupt_##name(int irq, void *data) \ { \ - struct device *dev = data; \ - struct talitos_private *priv = dev_get_drvdata(dev); \ + struct talitos_private *priv = data; \ u32 isr, isr_lo; \ unsigned long flags; \ \ @@ -765,7 +764,7 @@ static irqreturn_t talitos1_interrupt_##name(int irq, void *data) \ \ if (unlikely(isr & ch_err_mask || isr_lo & TALITOS1_IMR_LO_INIT)) { \ spin_unlock_irqrestore(&priv->reg_lock, flags); \ - talitos_error(dev, isr & ch_err_mask, isr_lo); \ + talitos_error(priv->dev, isr & ch_err_mask, isr_lo); \ } \ else { \ if (likely(isr & ch_done_mask)) { \ @@ -786,8 +785,7 @@ DEF_TALITOS1_INTERRUPT(4ch, TALITOS1_ISR_4CHDONE, TALITOS1_ISR_4CHERR, 0) #define DEF_TALITOS2_INTERRUPT(name, ch_done_mask, ch_err_mask, tlet) \ static irqreturn_t talitos2_interrupt_##name(int irq, void *data) \ { \ - struct device *dev = data; \ - struct talitos_private *priv = dev_get_drvdata(dev); \ + struct talitos_private *priv = data; \ u32 isr, isr_lo; \ unsigned long flags; \ \ @@ -800,7 +798,7 @@ static irqreturn_t talitos2_interrupt_##name(int irq, void *data) \ \ if (unlikely(isr & ch_err_mask || isr_lo)) { \ spin_unlock_irqrestore(&priv->reg_lock, flags); \ - talitos_error(dev, isr & ch_err_mask, isr_lo); \ + talitos_error(priv->dev, isr & ch_err_mask, isr_lo); \ } \ else { \ if (likely(isr & ch_done_mask)) { \ @@ -3242,7 +3240,7 @@ static void talitos_remove(struct platform_device *ofdev) for (i = 0; i < 2; i++) if (priv->irq[i] > 0) - free_irq(priv->irq[i], dev); + free_irq(priv->irq[i], priv); tasklet_kill(&priv->done_task[0]); if (priv->irq[1] > 0) @@ -3355,35 +3353,27 @@ static int talitos_probe_irq(struct platform_device *ofdev) int err; bool is_sec1 = has_ftr_sec1(priv); - priv->irq[0] = platform_get_irq(ofdev, 0); - if (priv->irq[0] < 0) - return priv->irq[0]; - if (is_sec1) { err = request_irq(priv->irq[0], talitos1_interrupt_4ch, 0, - dev_driver_string(dev), dev); + dev_driver_string(dev), priv); goto primary_out; } - priv->irq[1] = platform_get_irq_optional(ofdev, 1); - if (priv->irq[1] == -EPROBE_DEFER) - return priv->irq[1]; - - /* get the primary irq line */ + /* single (or primary) irq line */ if (priv->irq[1] < 0) { err = request_irq(priv->irq[0], talitos2_interrupt_4ch, 0, - dev_driver_string(dev), dev); + dev_driver_string(dev), priv); goto primary_out; } err = request_irq(priv->irq[0], talitos2_interrupt_ch0_2, 0, - dev_driver_string(dev), dev); + dev_driver_string(dev), priv); if (err) goto primary_out; - /* get the secondary irq line */ + /* secondary irq line */ err = request_irq(priv->irq[1], talitos2_interrupt_ch1_3, 0, - dev_driver_string(dev), dev); + dev_driver_string(dev), priv); if (err) { dev_err(dev, "failed to request secondary irq\n"); priv->irq[1] = 0; @@ -3394,7 +3384,9 @@ static int talitos_probe_irq(struct platform_device *ofdev) primary_out: if (err) { dev_err(dev, "failed to request primary irq\n"); + /* neither line is requested, keep remove() from freeing them */ priv->irq[0] = 0; + priv->irq[1] = 0; } return err; @@ -3406,12 +3398,27 @@ static int talitos_probe(struct platform_device *ofdev) struct device_node *np = ofdev->dev.of_node; struct talitos_private *priv; unsigned int num_channels; + void __iomem *reg; int i, err; int stride; + int irq0; + int irq1; if (of_property_read_u32(np, "fsl,num-channels", &num_channels)) return -EINVAL; + irq0 = platform_get_irq(ofdev, 0); + if (irq0 < 0) + return irq0; + + irq1 = platform_get_irq_optional(ofdev, 1); + if (irq1 == -EPROBE_DEFER) + return irq1; + + reg = devm_platform_ioremap_resource(ofdev, 0); + if (IS_ERR(reg)) + return PTR_ERR(reg); + priv = devm_kzalloc(dev, struct_size(priv, chan, num_channels), GFP_KERNEL); if (!priv) return -ENOMEM; @@ -3422,16 +3429,12 @@ static int talitos_probe(struct platform_device *ofdev) dev_set_drvdata(dev, priv); + priv->dev = dev; priv->ofdev = ofdev; spin_lock_init(&priv->reg_lock); - priv->reg = devm_platform_ioremap_resource(ofdev, 0); - if (IS_ERR(priv->reg)) { - dev_err(dev, "failed to of_iomap\n"); - err = PTR_ERR(priv->reg); - goto err_out; - } + priv->reg = reg; /* get SEC version capabilities from device tree */ of_property_read_u32(np, "fsl,channel-fifo-len", &priv->chfifo_len); @@ -3482,9 +3485,7 @@ static int talitos_probe(struct platform_device *ofdev) stride = TALITOS2_CH_STRIDE; } - err = talitos_probe_irq(ofdev); - if (err) - goto err_out; + priv->irq[0] = irq0; if (has_ftr_sec1(priv)) { if (priv->num_channels == 1) @@ -3494,6 +3495,7 @@ static int talitos_probe(struct platform_device *ofdev) tasklet_init(&priv->done_task[0], talitos1_done_4ch, (unsigned long)dev); } else { + priv->irq[1] = irq1; if (priv->irq[1] > 0) { tasklet_init(&priv->done_task[0], talitos2_done_ch0_2, (unsigned long)dev); @@ -3525,7 +3527,7 @@ static int talitos_probe(struct platform_device *ofdev) if (!priv->chan[i].fifo) { dev_err(dev, "failed to allocate request fifo %d\n", i); err = -ENOMEM; - goto err_out; + goto err_noirq; } atomic_set(&priv->chan[i].submit_count, @@ -3538,9 +3540,14 @@ static int talitos_probe(struct platform_device *ofdev) err = init_device(dev); if (err) { dev_err(dev, "failed to initialize device\n"); - goto err_out; + goto err_noirq; } + /* enable interrupts once the channel fifos and tasklets are set up */ + err = talitos_probe_irq(ofdev); + if (err) + goto err_out; + /* register the RNG, if available */ if (hw_supports(dev, DESC_HDR_SEL0_RNG)) { err = talitos_register_rng(dev); @@ -3598,6 +3605,10 @@ static int talitos_probe(struct platform_device *ofdev) return 0; +err_noirq: + /* the irq numbers are known, but the lines are not requested yet */ + priv->irq[0] = 0; + priv->irq[1] = 0; err_out: talitos_remove(ofdev); diff --git a/drivers/crypto/xilinx/zynqmp-aes-gcm.c b/drivers/crypto/xilinx/zynqmp-aes-gcm.c index d54c268dfe34..d9bd6dcd23a6 100644 --- a/drivers/crypto/xilinx/zynqmp-aes-gcm.c +++ b/drivers/crypto/xilinx/zynqmp-aes-gcm.c @@ -230,10 +230,8 @@ static int zynqmp_aes_aead_cipher(struct aead_request *req) } freemem: - memzero_explicit(kbuf, dma_size); - kfree(kbuf); - memzero_explicit(dmabuf, sizeof(struct zynqmp_aead_hw_req) + GCM_AES_IV_SIZE); - kfree(dmabuf); + kfree_sensitive(kbuf); + kfree_sensitive(dmabuf); return ret; } @@ -364,11 +362,9 @@ unmap: if (unlikely(dma_addr_hw_req)) dma_unmap_single(dev, dma_addr_hw_req, dmabuf_size, DMA_BIDIRECTIONAL); buf2_free: - memzero_explicit(dmabuf, dmabuf_size); - kfree(dmabuf); + kfree_sensitive(dmabuf); buf1_free: - memzero_explicit(kbuf, kbuf_size); - kfree(kbuf); + kfree_sensitive(kbuf); err: return ret; } @@ -766,7 +762,7 @@ static void xilinx_aes_aead_exit(struct crypto_aead *aead) struct xilinx_aead_tfm_ctx *tfm_ctx = crypto_tfm_ctx(tfm); dma_unmap_single(tfm_ctx->dev, tfm_ctx->key_dma_addr, AES_KEYSIZE_256, DMA_TO_DEVICE); - kfree(tfm_ctx->key); + kfree_sensitive(tfm_ctx->key); if (tfm_ctx->fbk_cipher) { crypto_free_aead(tfm_ctx->fbk_cipher); tfm_ctx->fbk_cipher = NULL; diff --git a/drivers/crypto/xilinx/zynqmp-sha.c b/drivers/crypto/xilinx/zynqmp-sha.c index 5813017b6b79..cd051e1f4275 100644 --- a/drivers/crypto/xilinx/zynqmp-sha.c +++ b/drivers/crypto/xilinx/zynqmp-sha.c @@ -59,7 +59,7 @@ static int zynqmp_sha_init_tfm(struct crypto_shash *hash) return PTR_ERR(fallback_tfm); if (crypto_shash_descsize(hash) < - crypto_shash_statesize(tfm_ctx->fbk_tfm)) { + crypto_shash_statesize(fallback_tfm)) { crypto_free_shash(fallback_tfm); return -EINVAL; } diff --git a/include/crypto/aes.h b/include/crypto/aes.h index 9fe868161e1d..fa5c3d363ac9 100644 --- a/include/crypto/aes.h +++ b/include/crypto/aes.h @@ -177,6 +177,19 @@ static inline int aes_check_keylen(size_t keylen) int aes_expandkey(struct crypto_aes_ctx *ctx, const u8 *in_key, unsigned int key_len); +/** + * aes_zeroize_ctx - Clear a crypto_aes_ctx structure + * @ctx: The location of the context that should be zeroized + * + * Explicitly fills the crypto_aes_ctx with zeroes. This should be done + * once the context is not required anymore to avoid that its contents + * are leaked on the stack or heap (if not using kfree_sensitive()). + */ +static inline void aes_zeroize_ctx(struct crypto_aes_ctx *ctx) +{ + memzero_explicit(ctx, sizeof(*ctx)); +} + /* * The following functions are temporarily exported for use by the AES mode * implementations in arch/$(SRCARCH)/crypto/. These exports will go away when diff --git a/include/linux/ccp.h b/include/linux/ccp.h index 868924dec5a1..e6c599243f11 100644 --- a/include/linux/ccp.h +++ b/include/linux/ccp.h @@ -26,7 +26,7 @@ struct ccp_cmd; /** * ccp_present - check if a CCP device is present * - * Returns zero if a CCP device is present, -ENODEV otherwise. + * Returns: zero if a CCP device is present, -ENODEV otherwise. */ int ccp_present(void); @@ -38,7 +38,7 @@ int ccp_present(void); /** * ccp_version - get the version of the CCP * - * Returns a positive version number, or zero if no CCP + * Returns: a positive version number, or zero if no CCP */ unsigned int ccp_version(void); @@ -61,9 +61,9 @@ unsigned int ccp_version(void); * will be -EINPROGRESS. Any other "err" value during callback is * the result of the operation. * - * The cmd has been successfully queued if: - * the return code is -EINPROGRESS or - * the return code is -EBUSY and CCP_CMD_MAY_BACKLOG flag is set + * Returns: The cmd has been successfully queued if: + * * the return code is -EINPROGRESS or + * * the return code is -EBUSY and CCP_CMD_MAY_BACKLOG flag is set */ int ccp_enqueue_cmd(struct ccp_cmd *cmd); @@ -89,7 +89,7 @@ static inline int ccp_enqueue_cmd(struct ccp_cmd *cmd) /***** AES engine *****/ /** - * ccp_aes_type - AES key size + * enum ccp_aes_type - AES key size * * @CCP_AES_TYPE_128: 128-bit key * @CCP_AES_TYPE_192: 192-bit key @@ -99,11 +99,12 @@ enum ccp_aes_type { CCP_AES_TYPE_128 = 0, CCP_AES_TYPE_192, CCP_AES_TYPE_256, + /* private: */ CCP_AES_TYPE__LAST, }; /** - * ccp_aes_mode - AES operation mode + * enum ccp_aes_mode - AES operation mode * * @CCP_AES_MODE_ECB: ECB mode * @CCP_AES_MODE_CBC: CBC mode @@ -111,6 +112,10 @@ enum ccp_aes_type { * @CCP_AES_MODE_CFB: CFB mode * @CCP_AES_MODE_CTR: CTR mode * @CCP_AES_MODE_CMAC: CMAC mode + * @CCP_AES_MODE_GHASH: GHASH mode + * @CCP_AES_MODE_GCTR: GCTR mode + * @CCP_AES_MODE_GCM: GCM mode + * @CCP_AES_MODE_GMAC: GMAC mode */ enum ccp_aes_mode { CCP_AES_MODE_ECB = 0, @@ -123,11 +128,12 @@ enum ccp_aes_mode { CCP_AES_MODE_GCTR, CCP_AES_MODE_GCM, CCP_AES_MODE_GMAC, + /* private: */ CCP_AES_MODE__LAST, }; /** - * ccp_aes_mode - AES operation mode + * enum ccp_aes_action - AES operation mode * * @CCP_AES_ACTION_DECRYPT: AES decrypt operation * @CCP_AES_ACTION_ENCRYPT: AES encrypt operation @@ -135,6 +141,7 @@ enum ccp_aes_mode { enum ccp_aes_action { CCP_AES_ACTION_DECRYPT = 0, CCP_AES_ACTION_ENCRYPT, + /* private: */ CCP_AES_ACTION__LAST, }; /* Overloaded field */ @@ -146,6 +153,7 @@ enum ccp_aes_action { * @type: AES operation key size * @mode: AES operation mode * @action: AES operation (decrypt/encrypt) + * @authsize: AES block request size * @key: key to be used for this AES operation * @key_len: length in bytes of key * @iv: IV to be used for this AES operation @@ -156,6 +164,7 @@ enum ccp_aes_action { * @cmac_final: indicates final operation when running in CMAC mode * @cmac_key: K1/K2 key used in final CMAC operation * @cmac_key_len: length in bytes of cmac_key + * @aad_len: length in bytes of Additional Authenticated Data * * Variables required to be set when calling ccp_enqueue_cmd(): * - type, mode, action, key, key_len, src, dst, src_len @@ -192,7 +201,7 @@ struct ccp_aes_engine { /***** XTS-AES engine *****/ /** - * ccp_xts_aes_unit_size - XTS unit size + * enum ccp_xts_aes_unit_size - XTS unit size * * @CCP_XTS_AES_UNIT_SIZE_16: Unit size of 16 bytes * @CCP_XTS_AES_UNIT_SIZE_512: Unit size of 512 bytes @@ -206,11 +215,13 @@ enum ccp_xts_aes_unit_size { CCP_XTS_AES_UNIT_SIZE_1024, CCP_XTS_AES_UNIT_SIZE_2048, CCP_XTS_AES_UNIT_SIZE_4096, + /* private: */ CCP_XTS_AES_UNIT_SIZE__LAST, }; /** * struct ccp_xts_aes_engine - CCP XTS AES operation + * @type: ccp_aes_type - AES key size * @action: AES operation (decrypt/encrypt) * @unit_size: unit size of the XTS operation * @key: key to be used for this XTS AES operation @@ -247,11 +258,13 @@ struct ccp_xts_aes_engine { /***** SHA engine *****/ /** - * ccp_sha_type - type of SHA operation + * enum ccp_sha_type - type of SHA operation * * @CCP_SHA_TYPE_1: SHA-1 operation * @CCP_SHA_TYPE_224: SHA-224 operation * @CCP_SHA_TYPE_256: SHA-256 operation + * @CCP_SHA_TYPE_384: SHA-384 operation + * @CCP_SHA_TYPE_512: SHA-512 operation */ enum ccp_sha_type { CCP_SHA_TYPE_1 = 1, @@ -259,6 +272,7 @@ enum ccp_sha_type { CCP_SHA_TYPE_256, CCP_SHA_TYPE_384, CCP_SHA_TYPE_512, + /* private: */ CCP_SHA_TYPE__LAST, }; @@ -384,7 +398,7 @@ struct ccp_rsa_engine { /***** Passthru engine *****/ /** - * ccp_passthru_bitwise - type of bitwise passthru operation + * enum ccp_passthru_bitwise - type of bitwise passthru operation * * @CCP_PASSTHRU_BITWISE_NOOP: no bitwise operation performed * @CCP_PASSTHRU_BITWISE_AND: perform bitwise AND of src with mask @@ -398,11 +412,12 @@ enum ccp_passthru_bitwise { CCP_PASSTHRU_BITWISE_OR, CCP_PASSTHRU_BITWISE_XOR, CCP_PASSTHRU_BITWISE_MASK, + /* private: */ CCP_PASSTHRU_BITWISE__LAST, }; /** - * ccp_passthru_byteswap - type of byteswap passthru operation + * enum ccp_passthru_byteswap - type of byteswap passthru operation * * @CCP_PASSTHRU_BYTESWAP_NOOP: no byte swapping performed * @CCP_PASSTHRU_BYTESWAP_32BIT: swap bytes within 32-bit words @@ -412,6 +427,7 @@ enum ccp_passthru_byteswap { CCP_PASSTHRU_BYTESWAP_NOOP = 0, CCP_PASSTHRU_BYTESWAP_32BIT, CCP_PASSTHRU_BYTESWAP_256BIT, + /* private: */ CCP_PASSTHRU_BYTESWAP__LAST, }; @@ -450,8 +466,8 @@ struct ccp_passthru_engine { * @byte_swap: byteswap operation to perform * @mask: mask to be applied to data * @mask_len: length in bytes of mask - * @src: data to be used for this operation - * @dst: data produced by this operation + * @src_dma: data to be used for this operation + * @dst_dma: data produced by this operation * @src_len: length in bytes of data used for this operation * @final: indicate final pass-through operation * @@ -478,7 +494,7 @@ struct ccp_passthru_nomap_engine { #define CCP_ECC_MAX_OUTPUTS 3 /** - * ccp_ecc_function - type of ECC function + * enum ccp_ecc_function - type of ECC function * * @CCP_ECC_FUNCTION_MMUL_384BIT: 384-bit modular multiplication * @CCP_ECC_FUNCTION_MADD_384BIT: 384-bit modular addition @@ -564,8 +580,9 @@ struct ccp_ecc_point_math { * @function: ECC function to perform * @mod: ECC modulus * @mod_len: length in bytes of modulus - * @mm: module math parameters - * @pm: point math parameters + * @u: union for math parameters + * @u.mm: module math parameters + * @u.pm: point math parameters * @ecc_result: result of the ECC operation * * Variables required to be set when calling ccp_enqueue_cmd(): @@ -589,11 +606,11 @@ struct ccp_ecc_engine { /** - * ccp_engine - CCP operation identifiers + * enum ccp_engine - CCP operation identifiers * * @CCP_ENGINE_AES: AES operation - * @CCP_ENGINE_XTS_AES: 128-bit XTS AES operation - * @CCP_ENGINE_RSVD1: unused + * @CCP_ENGINE_XTS_AES_128: 128-bit XTS AES operation + * @CCP_ENGINE_DES3: 3DES operation * @CCP_ENGINE_SHA: SHA operation * @CCP_ENGINE_RSA: RSA operation * @CCP_ENGINE_PASSTHRU: pass-through operation @@ -609,6 +626,7 @@ enum ccp_engine { CCP_ENGINE_PASSTHRU, CCP_ENGINE_ZLIB_DECOMPRESS, CCP_ENGINE_ECC, + /* private: */ CCP_ENGINE__LAST, }; diff --git a/include/linux/hisi_acc_qm.h b/include/linux/hisi_acc_qm.h index f7570a409905..f2885d60b468 100644 --- a/include/linux/hisi_acc_qm.h +++ b/include/linux/hisi_acc_qm.h @@ -196,7 +196,7 @@ struct qm_dev_dfx { }; struct dfx_diff_registers { - u32 *regs; + u32 *regs __counted_by_ptr(reg_len); u32 reg_offset; u32 reg_len; }; @@ -332,9 +332,9 @@ struct hisi_qm_cap_record { struct hisi_qm_cap_tables { u32 qm_cap_size; - struct hisi_qm_cap_record *qm_cap_table; + struct hisi_qm_cap_record *qm_cap_table __counted_by_ptr(qm_cap_size); u32 dev_cap_size; - struct hisi_qm_cap_record *dev_cap_table; + struct hisi_qm_cap_record *dev_cap_table __counted_by_ptr(dev_cap_size); }; struct hisi_qm_list { diff --git a/include/linux/psp-sev.h b/include/linux/psp-sev.h index 03a79786df1d..fab62228f981 100644 --- a/include/linux/psp-sev.h +++ b/include/linux/psp-sev.h @@ -49,7 +49,7 @@ #define SEV_FW_BLOB_MAX_SIZE 0x4000 /* 16KB */ -/** +/* * SEV platform state */ enum sev_state { @@ -60,7 +60,7 @@ enum sev_state { SEV_STATE_MAX }; -/** +/* * SEV platform and guest management commands */ enum sev_cmd { @@ -157,6 +157,7 @@ enum sev_cmd { * struct sev_data_init - INIT command parameters * * @flags: processing flags + * @reserved: reserved * @tmr_address: system physical address used for SEV-ES * @tmr_len: len of tmr_address */ @@ -174,6 +175,7 @@ struct sev_data_init { * @flags: processing flags * @tmr_address: system physical address used for SEV-ES * @tmr_len: len of tmr_address + * @reserved: reserved * @nv_address: system physical address used for PSP NV storage * @nv_len: len of nv_address */ @@ -201,12 +203,13 @@ struct sev_data_pek_csr { } __packed; /** - * struct sev_data_cert_import - PEK_CERT_IMPORT command parameters + * struct sev_data_pek_cert_import - PEK_CERT_IMPORT command parameters * - * @pek_address: PEK certificate chain - * @pek_len: len of PEK certificate - * @oca_address: OCA certificate chain - * @oca_len: len of OCA certificate + * @pek_cert_address: PEK certificate chain + * @pek_cert_len: len of PEK certificate + * @reserved: reserved + * @oca_cert_address: OCA certificate chain + * @oca_cert_len: len of OCA certificate */ struct sev_data_pek_cert_import { u64 pek_cert_address; /* In */ @@ -240,8 +243,9 @@ struct sev_data_get_id { /** * struct sev_data_pdh_cert_export - PDH_CERT_EXPORT command parameters * - * @pdh_address: PDH certificate address - * @pdh_len: len of PDH certificate + * @pdh_cert_address: PDH certificate address + * @pdh_cert_len: len of PDH certificate + * @reserved: reserved * @cert_chain_address: PDH certificate chain * @cert_chain_len: len of PDH certificate chain */ @@ -304,6 +308,7 @@ struct sev_data_guest_status { * @policy: guest launch policy * @dh_cert_address: physical address of DH certificate blob * @dh_cert_len: len of DH certificate blob + * @reserved: reserved * @session_address: physical address of session parameters * @session_len: len of session parameters */ @@ -321,6 +326,7 @@ struct sev_data_launch_start { * struct sev_data_launch_update_data - LAUNCH_UPDATE_DATA command parameter * * @handle: handle of the VM to update + * @reserved: reserved * @len: len of memory to be encrypted * @address: physical address of memory region to encrypt */ @@ -335,6 +341,7 @@ struct sev_data_launch_update_data { * struct sev_data_launch_update_vmsa - LAUNCH_UPDATE_VMSA command * * @handle: handle of the VM + * @reserved: reserved * @address: physical address of memory region to encrypt * @len: len of memory region to encrypt */ @@ -349,6 +356,7 @@ struct sev_data_launch_update_vmsa { * struct sev_data_launch_measure - LAUNCH_MEASURE command parameters * * @handle: handle of the VM to process + * @reserved: reserved * @address: physical address containing the measurement blob * @len: len of measurement blob */ @@ -363,10 +371,13 @@ struct sev_data_launch_measure { * struct sev_data_launch_secret - LAUNCH_SECRET command parameters * * @handle: handle of the VM to process + * @reserved1: reserved * @hdr_address: physical address containing the packet header * @hdr_len: len of packet header + * @reserved2: reserved * @guest_address: system physical address of guest memory region * @guest_len: len of guest_paddr + * @reserved3: reserved * @trans_address: physical address of transport memory buffer * @trans_len: len of transport memory buffer */ @@ -399,10 +410,13 @@ struct sev_data_launch_finish { * @policy: policy information for the VM * @pdh_cert_address: physical address containing PDH certificate * @pdh_cert_len: len of PDH certificate + * @reserved1: reserved * @plat_certs_address: physical address containing platform certificate * @plat_certs_len: len of platform certificate + * @reserved2: reserved * @amd_certs_address: physical address containing AMD certificate * @amd_certs_len: len of AMD certificate + * @reserved3: reserved * @session_address: physical address containing Session data * @session_len: len of session data */ @@ -423,13 +437,16 @@ struct sev_data_send_start { } __packed; /** - * struct sev_data_send_update - SEND_UPDATE_DATA command + * struct sev_data_send_update_data - SEND_UPDATE_DATA command * * @handle: handle of the VM to process + * @reserved1: reserved * @hdr_address: physical address containing packet header * @hdr_len: len of packet header + * @reserved2: reserved * @guest_address: physical address of guest memory region to send * @guest_len: len of guest memory region to send + * @reserved3: reserved * @trans_address: physical address of host memory region * @trans_len: len of host memory region */ @@ -447,13 +464,15 @@ struct sev_data_send_update_data { } __packed; /** - * struct sev_data_send_update - SEND_UPDATE_VMSA command + * struct sev_data_send_update_vmsa - SEND_UPDATE_VMSA command * * @handle: handle of the VM to process * @hdr_address: physical address containing packet header * @hdr_len: len of packet header + * @reserved2: reserved * @guest_address: physical address of guest memory region to send * @guest_len: len of guest memory region to send + * @reserved3: reserved * @trans_address: physical address of host memory region * @trans_len: len of host memory region */ @@ -491,8 +510,10 @@ struct sev_data_send_cancel { * struct sev_data_receive_start - RECEIVE_START command parameters * * @handle: handle of the VM to perform receive operation + * @policy: policy information for the VM * @pdh_cert_address: system physical address containing PDH certificate blob * @pdh_cert_len: len of PDH certificate blob + * @reserved1: reserved * @session_address: system physical address containing session blob * @session_len: len of session blob */ @@ -510,10 +531,13 @@ struct sev_data_receive_start { * struct sev_data_receive_update_data - RECEIVE_UPDATE_DATA command parameters * * @handle: handle of the VM to update + * @reserved1: reserved * @hdr_address: physical address containing packet header blob * @hdr_len: len of packet header + * @reserved2: reserved * @guest_address: system physical address of guest memory region * @guest_len: len of guest memory region + * @reserved3: reserved * @trans_address: system physical address of transport buffer * @trans_len: len of transport buffer */ @@ -534,10 +558,13 @@ struct sev_data_receive_update_data { * struct sev_data_receive_update_vmsa - RECEIVE_UPDATE_VMSA command parameters * * @handle: handle of the VM to update + * @reserved1: reserved * @hdr_address: physical address containing packet header blob * @hdr_len: len of packet header + * @reserved2: reserved * @guest_address: system physical address of guest memory region * @guest_len: len of guest memory region + * @reserved3: reserved * @trans_address: system physical address of transport buffer * @trans_len: len of transport buffer */ @@ -567,6 +594,7 @@ struct sev_data_receive_finish { * struct sev_data_dbg - DBG_ENCRYPT/DBG_DECRYPT command parameters * * @handle: handle of the VM to perform debug operation + * @reserved: reserved * @src_addr: source address of data to operate on * @dst_addr: destination address of data to operate on * @len: len of data to operate on @@ -583,6 +611,7 @@ struct sev_data_dbg { * struct sev_data_attestation_report - SEV_ATTESTATION_REPORT command parameters * * @handle: handle of the VM + * @reserved: reserved * @mnonce: a random nonce that will be included in the report. * @address: physical address where the report will be copied. * @len: length of the physical buffer. @@ -781,9 +810,14 @@ struct sev_data_snp_guest_request { * * @init_rmp: indicate that the RMP should be initialized. * @list_paddr_en: indicate that list_paddr is valid + * @rapl_dis: whether RAPL is disabled + * @ciphertext_hiding_en: whether ciphertext hiding is enabled + * @tio_en: Indicates that SNP_INIT_EX initialized the RMP for SEV-TIO * @rsvd: reserved * @rsvd1: reserved * @list_paddr: system physical address of range list + * @max_snp_asid: When non-zero, enable ciphertext hiding and specify the + * maximum ASID that can be used for an SEV-SNP guest. * @rsvd2: reserved */ struct sev_data_snp_init_ex { @@ -841,7 +875,7 @@ struct sev_data_snp_shutdown_ex { } __packed; /** - * struct sev_platform_init_args + * struct sev_platform_init_args - parameters for sev_platform_init() * * @error: SEV firmware error code * @probe: True if this is being called as part of CCP module probe, which @@ -879,12 +913,12 @@ struct sev_data_snp_feature_info { } __packed; /** - * struct feature_info - FEATURE_INFO structure + * struct snp_feature_info - FEATURE_INFO structure * * @eax: output of SNP_FEATURE_INFO command * @ebx: output of SNP_FEATURE_INFO command * @ecx: output of SNP_FEATURE_INFO command - * #edx: output of SNP_FEATURE_INFO command + * @edx: output of SNP_FEATURE_INFO command */ struct snp_feature_info { u32 eax; @@ -954,7 +988,7 @@ struct sev_data_snp_verify_mitigation_dst { } __packed; /** - * struct sev_snp_tcb_version_genoa_milan + * struct sev_snp_tcb_version_genoa_milan - v1 SVN payload * * @boot_loader: SVN of PSP bootloader * @tee: SVN of PSP operating system @@ -971,7 +1005,7 @@ struct sev_snp_tcb_version_genoa_milan { }; /** - * struct sev_snp_tcb_version_turin + * struct sev_snp_tcb_version_turin - v2 SVN payload * * @fmc: SVN of FMC firmware * @boot_loader: SVN of PSP bootloader @@ -1037,9 +1071,9 @@ int sev_platform_status(struct sev_user_data_status *status, int *error); * behalf of userspace. The caller must pass a valid SEV file descriptor * so that we know that it has access to SEV device. * - * @filep - SEV device file pointer - * @cmd - command to issue - * @data - command buffer + * @filep: SEV device file pointer + * @id: command to issue + * @data: command buffer * @error: SEV command return code * * Returns: @@ -1056,8 +1090,8 @@ int sev_issue_cmd_external_user(struct file *filep, unsigned int id, /** * sev_guest_deactivate - perform SEV DEACTIVATE command * - * @deactivate: sev_data_deactivate structure to be processed - * @sev_ret: sev command return code + * @data: sev_data_deactivate structure to be processed + * @error: sev command return code * * Returns: * 0 if the sev successfully processed the command @@ -1071,8 +1105,8 @@ int sev_guest_deactivate(struct sev_data_deactivate *data, int *error); /** * sev_guest_activate - perform SEV ACTIVATE command * - * @activate: sev_data_activate structure to be processed - * @sev_ret: sev command return code + * @data: sev_data_activate structure to be processed + * @error: sev command return code * * Returns: * 0 if the sev successfully processed the command @@ -1086,7 +1120,7 @@ int sev_guest_activate(struct sev_data_activate *data, int *error); /** * sev_guest_df_flush - perform SEV DF_FLUSH command * - * @sev_ret: sev command return code + * @error: sev command return code * * Returns: * 0 if the sev successfully processed the command @@ -1100,8 +1134,8 @@ int sev_guest_df_flush(int *error); /** * sev_guest_decommission - perform SEV DECOMMISSION command * - * @decommission: sev_data_decommission structure to be processed - * @sev_ret: sev command return code + * @data: sev_data_decommission structure to be processed + * @error: sev command return code * * Returns: * 0 if the sev successfully processed the command diff --git a/include/linux/rhashtable-types.h b/include/linux/rhashtable-types.h index 57c11ec9dc64..3576b8f08aff 100644 --- a/include/linux/rhashtable-types.h +++ b/include/linux/rhashtable-types.h @@ -70,6 +70,12 @@ struct rhashtable_params { rht_obj_cmpfn_t obj_cmpfn; }; +struct rhashtable_lockdep_keys { + struct lock_class_key lock_key; + struct lock_class_key mutex_key; + struct lock_class_key bucket_key; +}; + /** * struct rhashtable - Hash table handle * @tbl: Bucket table @@ -97,6 +103,9 @@ struct rhashtable { #ifdef CONFIG_MEM_ALLOC_PROFILING struct alloc_tag *alloc_tag; #endif +#ifdef CONFIG_LOCKDEP + struct lock_class_key *lockdep_key; +#endif }; /** @@ -138,24 +147,77 @@ struct rhashtable_iter { int __rhashtable_init_noprof(struct rhashtable *ht, const struct rhashtable_params *params, - struct lock_class_key *key); + struct rhashtable_lockdep_keys *keys); #define rhashtable_init_noprof(ht, params) \ ({ \ - static struct lock_class_key __key; \ + static struct rhashtable_lockdep_keys __keys; \ \ - __rhashtable_init_noprof(ht, params, &__key); \ + __rhashtable_init_noprof(ht, params, &__keys); \ }) + +/** + * rhashtable_init - initialize a new hash table + * @ht: hash table to be initialized + * @params: configuration parameters + * + * Initializes a new hash table based on the provided configuration + * parameters. A table can be configured either with a variable or + * fixed length key: + * + * Configuration Example 1: Fixed length keys + * struct test_obj { + * int key; + * void * my_member; + * struct rhash_head node; + * }; + * + * struct rhashtable_params params = { + * .head_offset = offsetof(struct test_obj, node), + * .key_offset = offsetof(struct test_obj, key), + * .key_len = sizeof(int), + * .hashfn = jhash, + * }; + * + * Configuration Example 2: Variable length keys + * struct test_obj { + * [...] + * struct rhash_head node; + * }; + * + * u32 my_hash_fn(const void *data, u32 len, u32 seed) + * { + * struct test_obj *obj = data; + * + * return [... hash ...]; + * } + * + * struct rhashtable_params params = { + * .head_offset = offsetof(struct test_obj, node), + * .hashfn = jhash, + * .obj_hashfn = my_hash_fn, + * }; + */ #define rhashtable_init(...) alloc_hooks(rhashtable_init_noprof(__VA_ARGS__)) int __rhltable_init_noprof(struct rhltable *hlt, const struct rhashtable_params *params, - struct lock_class_key *key); + struct rhashtable_lockdep_keys *keys); #define rhltable_init_noprof(hlt, params) \ ({ \ - static struct lock_class_key __key; \ + static struct rhashtable_lockdep_keys __keys; \ \ - __rhltable_init_noprof(hlt, params, &__key); \ + __rhltable_init_noprof(hlt, params, &__keys); \ }) + +/** + * rhltable_init - initialize a new hash list table + * @hlt: hash list table to be initialized + * @params: configuration parameters + * + * Initializes a new hash list table. + * + * See documentation for rhashtable_init. + */ #define rhltable_init(...) alloc_hooks(rhltable_init_noprof(__VA_ARGS__)) #endif /* _LINUX_RHASHTABLE_TYPES_H */ diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h index 57a2a29bef0e..70dac9214617 100644 --- a/include/linux/rhashtable.h +++ b/include/linux/rhashtable.h @@ -319,18 +319,6 @@ static inline struct rhash_lock_head __rcu **rht_bucket_insert( * When we write to a bucket without unlocking, we use rht_assign_locked(). */ -static inline unsigned long rht_lock(struct bucket_table *tbl, - struct rhash_lock_head __rcu **bkt) - __acquires(__bitlock(0, bkt)) -{ - unsigned long flags; - - local_irq_save(flags); - bit_spin_lock(0, (unsigned long *)bkt); - lock_map_acquire(&tbl->dep_map); - return flags; -} - static inline unsigned long rht_lock_nested(struct bucket_table *tbl, struct rhash_lock_head __rcu **bucket, unsigned int subclass) @@ -344,6 +332,13 @@ static inline unsigned long rht_lock_nested(struct bucket_table *tbl, return flags; } +static inline unsigned long rht_lock(struct bucket_table *tbl, + struct rhash_lock_head __rcu **bkt) + __acquires(__bitlock(0, bkt)) +{ + return rht_lock_nested(tbl, bkt, 0); +} + static inline void rht_unlock(struct bucket_table *tbl, struct rhash_lock_head __rcu **bkt, unsigned long flags) @@ -598,13 +593,23 @@ static inline void rht_assign_unlock(struct bucket_table *tbl, for (pos = list; pos && rht_entry(tpos, pos, member); \ pos = rcu_dereference_all(pos->next)) -static inline int rhashtable_compare(struct rhashtable_compare_arg *arg, - const void *obj) +/* + * Use constant params from inlined callers to specialize memcmp(). If params + * isn't constant, it must be equal to ht->p. + */ +static __always_inline int rhashtable_compare(struct rhashtable_compare_arg *arg, + const void *obj, + const struct rhashtable_params params) { struct rhashtable *ht = arg->ht; const char *ptr = obj; - return memcmp(ptr + ht->p.key_offset, arg->key, ht->p.key_len); + if (!__builtin_constant_p(params.key_len)) + return memcmp(ptr + ht->p.key_offset, arg->key, + ht->p.key_len); + + return memcmp(ptr + params.key_offset, arg->key, + params.key_len ? : ht->p.key_len); } /* Internal function, do not use. */ @@ -632,7 +637,7 @@ restart: rht_for_each_rcu_from(he, __rht_ptr_rcu(bkt, freq), tbl, hash) { if (params.obj_cmpfn ? params.obj_cmpfn(&arg, rht_obj(ht, he)) : - rhashtable_compare(&arg, rht_obj(ht, he))) + rhashtable_compare(&arg, rht_obj(ht, he), params)) continue; return he; } @@ -797,7 +802,7 @@ slow_path: if (!key || (params.obj_cmpfn ? params.obj_cmpfn(&arg, rht_obj(ht, head)) : - rhashtable_compare(&arg, rht_obj(ht, head)))) { + rhashtable_compare(&arg, rht_obj(ht, head), params))) { pprev = &head->next; continue; } diff --git a/include/uapi/linux/psp-sev.h b/include/uapi/linux/psp-sev.h index 52dae70b058b..536626abe6db 100644 --- a/include/uapi/linux/psp-sev.h +++ b/include/uapi/linux/psp-sev.h @@ -15,7 +15,7 @@ #include <linux/types.h> -/** +/* * SEV platform commands */ enum { @@ -36,7 +36,7 @@ enum { SEV_MAX, }; -/** +/* * SEV Firmware status code */ typedef enum { @@ -109,8 +109,8 @@ typedef enum { /** * struct sev_user_data_status - PLATFORM_STATUS command parameters * - * @major: major API version - * @minor: minor API version + * @api_major: major API version + * @api_minor: minor API version * @state: platform state * @flags: platform config flags * @build: firmware build id for API version @@ -139,12 +139,12 @@ struct sev_user_data_pek_csr { } __packed; /** - * struct sev_user_data_cert_import - PEK_CERT_IMPORT command parameters + * struct sev_user_data_pek_cert_import - PEK_CERT_IMPORT command parameters * - * @pek_address: PEK certificate chain - * @pek_len: length of PEK certificate - * @oca_address: OCA certificate chain - * @oca_len: length of OCA certificate + * @pek_cert_address: PEK certificate chain + * @pek_cert_len: length of PEK certificate + * @oca_cert_address: OCA certificate chain + * @oca_cert_len: length of OCA certificate */ struct sev_user_data_pek_cert_import { __u64 pek_cert_address; /* In */ @@ -156,8 +156,8 @@ struct sev_user_data_pek_cert_import { /** * struct sev_user_data_pdh_cert_export - PDH_CERT_EXPORT command parameters * - * @pdh_address: PDH certificate address - * @pdh_len: length of PDH certificate + * @pdh_cert_address: PDH certificate address + * @pdh_cert_len: length of PDH certificate * @cert_chain_address: PDH certificate chain * @cert_chain_len: length of PDH certificate chain */ @@ -248,7 +248,7 @@ struct sev_user_data_snp_config { } __packed; /** - * struct sev_data_snp_vlek_load - SNP_VLEK_LOAD structure + * struct sev_user_data_snp_vlek_load - SNP_VLEK_LOAD structure * * @len: length of the command buffer read by the PSP * @vlek_wrapped_version: version of wrapped VLEK hashstick (Must be 0h) @@ -264,7 +264,7 @@ struct sev_user_data_snp_vlek_load { } __packed; /** - * struct sev_user_data_snp_vlek_wrapped_vlek_hashstick - Wrapped VLEK data + * struct sev_user_data_snp_wrapped_vlek_hashstick - Wrapped VLEK data * * @data: Opaque data provided by AMD KDS (as described in SEV-SNP Firmware ABI * 1.54, SNP_VLEK_LOAD) diff --git a/kernel/padata.c b/kernel/padata.c index 0d3ea1b68b1f..5a113c667d4c 100644 --- a/kernel/padata.c +++ b/kernel/padata.c @@ -534,7 +534,7 @@ static void padata_init_reorder_list(struct parallel_data *pd) } } -/* Allocate and initialize the internal cpumask dependend resources. */ +/* Allocate and initialize the internal cpumask dependent resources. */ static struct parallel_data *padata_alloc_pd(struct padata_shell *ps, int offlining_cpu) { diff --git a/lib/842/842_decompress.c b/lib/842/842_decompress.c index 582085ef8b49..45a9815abd63 100644 --- a/lib/842/842_decompress.c +++ b/lib/842/842_decompress.c @@ -165,6 +165,9 @@ static int __do_index(struct sw842_param *p, u8 size, u8 bits, u64 fsize) u64 index, offset, total = round_down(p->out - p->ostart, 8); int ret; + if (size > p->olen) + return -ENOSPC; + ret = next_bits(p, &index, bits); if (ret) return ret; @@ -306,7 +309,7 @@ int sw842_decompress(const u8 *in, unsigned int ilen, if (ret) return ret; - if (p.out == out) /* no previous bytes */ + if (p.out - p.ostart < 8) /* no complete previous block */ return -EINVAL; /* copy rep + 1 */ @@ -344,6 +347,8 @@ int sw842_decompress(const u8 *in, unsigned int ilen, if (!bytes || bytes > SHORT_DATA_BITS_MAX) return -EINVAL; + if (bytes > p.olen) + return -ENOSPC; while (bytes-- > 0) { ret = next_bits(&p, &tmp, 8); diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 4b9b337df256..004188ac0d52 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -2239,6 +2239,21 @@ menuconfig RUNTIME_TESTING_MENU if RUNTIME_TESTING_MENU +config 842_DECOMPRESS_KUNIT_TEST + tristate "KUnit tests for the 842 decompressor" if !KUNIT_ALL_TESTS + depends on KUNIT + depends on 842_DECOMPRESS + default KUNIT_ALL_TESTS + help + Enable stream-validation and boundary tests for the software 842 + decompressor. The tests exercise indexed copies, short data and + repeat operations at valid and invalid output or history boundaries. + + For more information on KUnit and unit tests in general, refer to + Documentation/dev-tools/kunit/. + + If unsure, say N. + config TEST_DHRY tristate "Dhrystone benchmark test" help diff --git a/lib/rhashtable.c b/lib/rhashtable.c index 6362896e4f09..500c45cd1304 100644 --- a/lib/rhashtable.c +++ b/lib/rhashtable.c @@ -191,7 +191,6 @@ static struct bucket_table *bucket_table_alloc(struct rhashtable *ht, struct bucket_table *tbl = NULL; size_t size; int i; - static struct lock_class_key __key; tbl = alloc_hooks_tag(ht->alloc_tag, kvmalloc_node_align_noprof(struct_size(tbl, buckets, nbuckets), @@ -207,7 +206,9 @@ static struct bucket_table *bucket_table_alloc(struct rhashtable *ht, if (tbl == NULL) return NULL; - lockdep_init_map(&tbl->dep_map, "rhashtable_bucket", &__key, 0); +#ifdef CONFIG_LOCKDEP + lockdep_init_map(&tbl->dep_map, "rhashtable_bucket", ht->lockdep_key, 0); +#endif tbl->size = size; @@ -548,7 +549,7 @@ static void *rhashtable_lookup_one(struct rhashtable *ht, if (!key || (ht->p.obj_cmpfn ? ht->p.obj_cmpfn(&arg, rht_obj(ht, head)) : - rhashtable_compare(&arg, rht_obj(ht, head)))) { + rhashtable_compare(&arg, rht_obj(ht, head), ht->p))) { pprev = &head->next; continue; } @@ -710,7 +711,8 @@ static struct rhash_head *__rhashtable_next_in_table( rht_for_each_rcu(he, tbl, b) { bool match = params.obj_cmpfn ? !params.obj_cmpfn(&arg, rht_obj(ht, he)) - : !rhashtable_compare(&arg, rht_obj(ht, he)); + : !rhashtable_compare(&arg, rht_obj(ht, he), + params); if (found) { if (match) continue; @@ -1120,51 +1122,9 @@ static u32 rhashtable_jhash2(const void *key, u32 length, u32 seed) return jhash2(key, length, seed); } -/** - * rhashtable_init - initialize a new hash table - * @ht: hash table to be initialized - * @params: configuration parameters - * - * Initializes a new hash table based on the provided configuration - * parameters. A table can be configured either with a variable or - * fixed length key: - * - * Configuration Example 1: Fixed length keys - * struct test_obj { - * int key; - * void * my_member; - * struct rhash_head node; - * }; - * - * struct rhashtable_params params = { - * .head_offset = offsetof(struct test_obj, node), - * .key_offset = offsetof(struct test_obj, key), - * .key_len = sizeof(int), - * .hashfn = jhash, - * }; - * - * Configuration Example 2: Variable length keys - * struct test_obj { - * [...] - * struct rhash_head node; - * }; - * - * u32 my_hash_fn(const void *data, u32 len, u32 seed) - * { - * struct test_obj *obj = data; - * - * return [... hash ...]; - * } - * - * struct rhashtable_params params = { - * .head_offset = offsetof(struct test_obj, node), - * .hashfn = jhash, - * .obj_hashfn = my_hash_fn, - * }; - */ int __rhashtable_init_noprof(struct rhashtable *ht, - const struct rhashtable_params *params, - struct lock_class_key *key) + const struct rhashtable_params *params, + struct rhashtable_lockdep_keys *keys) { struct bucket_table *tbl; size_t size; @@ -1174,8 +1134,12 @@ int __rhashtable_init_noprof(struct rhashtable *ht, return -EINVAL; memset(ht, 0, sizeof(*ht)); - mutex_init_with_key(&ht->mutex, key); + mutex_init_with_key(&ht->mutex, &keys->mutex_key); spin_lock_init(&ht->lock); + lockdep_set_class(&ht->lock, &keys->lock_key); +#ifdef CONFIG_LOCKDEP + ht->lockdep_key = &keys->bucket_key; +#endif memcpy(&ht->p, params, sizeof(*params)); alloc_tag_record(ht->alloc_tag); @@ -1228,22 +1192,13 @@ int __rhashtable_init_noprof(struct rhashtable *ht, } EXPORT_SYMBOL_GPL(__rhashtable_init_noprof); -/** - * rhltable_init - initialize a new hash list table - * @hlt: hash list table to be initialized - * @params: configuration parameters - * - * Initializes a new hash list table. - * - * See documentation for rhashtable_init. - */ int __rhltable_init_noprof(struct rhltable *hlt, const struct rhashtable_params *params, - struct lock_class_key *key) + struct rhashtable_lockdep_keys *keys) { int err; - err = __rhashtable_init_noprof(&hlt->ht, params, key); + err = __rhashtable_init_noprof(&hlt->ht, params, keys); hlt->ht.rhlist = true; return err; } diff --git a/lib/tests/842_decompress_kunit.c b/lib/tests/842_decompress_kunit.c new file mode 100644 index 000000000000..11202ba9539b --- /dev/null +++ b/lib/tests/842_decompress_kunit.c @@ -0,0 +1,144 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include <kunit/test.h> +#include <linux/sw842.h> + +#define SW842_GUARD_SIZE 8 +#define SW842_MAX_OUTPUT 16 +#define SW842_GUARD_BYTE 0x42 +#define SW842_OUTPUT_POISON 0x5a + +/* ZEROS, I8(0), END, CRC32. */ +static const u8 sw842_index_exact_fit[] = { + 0xe6, 0x40, 0x3c, 0x00, 0x00, 0x00, 0x00, +}; + +/* D8(eight zero bytes), I8(0), END, CRC32. */ +static const u8 sw842_index_output_overflow[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x06, 0x40, 0x3c, 0x00, 0x00, 0x00, 0x00, +}; + +/* ZEROS, SHORT_DATA(01 02 03 04 05), END, CRC32. */ +static const u8 sw842_short_data_exact_fit[] = { + 0xe7, 0x68, 0x08, 0x10, 0x18, 0x20, + 0x2f, 0xa9, 0x67, 0xfc, 0x07, 0xc0, +}; + +/* ZEROS, SHORT_DATA(five zero bytes), END, CRC32. */ +static const u8 sw842_short_data_output_overflow[] = { + 0xe7, 0x48, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, +}; + +/* ZEROS, REPEAT(one block), END, CRC32. */ +static const u8 sw842_repeat_exact_history[] = { + 0xe6, 0xc0, 0xf0, 0x00, 0x00, 0x00, 0x00, +}; + +/* + * SHORT_DATA(seven zero bytes), REPEAT(one block), END, CRC32. + * CRC32 includes SW842_GUARD_BYTE copied from before output into byte 7. + */ +static const u8 sw842_repeat_without_full_history[] = { + 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xd8, 0x1e, 0x09, 0xa3, 0x1d, 0xd6, +}; + +static const u8 sw842_zero_output[SW842_MAX_OUTPUT]; +static const u8 sw842_short_data_output[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x02, 0x03, 0x04, 0x05, +}; + +struct sw842_decompress_test_case { + const char *name; + const u8 *compressed; + unsigned int compressed_len; + const u8 *expected_output; + unsigned int output_capacity; + int expected_ret; +}; + +#define SW842_DECOMPRESS_CASE(_name, _compressed, _compressed_len, _expected, \ + _capacity, _ret) \ + { \ + .name = _name, \ + .compressed = _compressed, \ + .compressed_len = _compressed_len, \ + .expected_output = _expected, \ + .output_capacity = _capacity, \ + .expected_ret = _ret, \ + } + +static const struct sw842_decompress_test_case sw842_decompress_cases[] = { + SW842_DECOMPRESS_CASE("index_exact_fit", sw842_index_exact_fit, + ARRAY_SIZE(sw842_index_exact_fit), + sw842_zero_output, 16, 0), + SW842_DECOMPRESS_CASE("index_output_overflow", + sw842_index_output_overflow, + ARRAY_SIZE(sw842_index_output_overflow), + sw842_zero_output, 8, -ENOSPC), + SW842_DECOMPRESS_CASE("short_data_exact_fit", + sw842_short_data_exact_fit, + ARRAY_SIZE(sw842_short_data_exact_fit), + sw842_short_data_output, + sizeof(sw842_short_data_output), 0), + SW842_DECOMPRESS_CASE("short_data_output_overflow", + sw842_short_data_output_overflow, + ARRAY_SIZE(sw842_short_data_output_overflow), + sw842_zero_output, 8, -ENOSPC), + SW842_DECOMPRESS_CASE("repeat_exact_history", + sw842_repeat_exact_history, + ARRAY_SIZE(sw842_repeat_exact_history), + sw842_zero_output, 16, 0), + SW842_DECOMPRESS_CASE("repeat_without_full_history", + sw842_repeat_without_full_history, + ARRAY_SIZE(sw842_repeat_without_full_history), + sw842_zero_output, 15, -EINVAL), +}; + +KUNIT_ARRAY_PARAM_DESC(sw842_decompress, sw842_decompress_cases, name); + +static void sw842_decompress_test(struct kunit *test) +{ + const struct sw842_decompress_test_case *test_case = test->param_value; + u8 storage[SW842_GUARD_SIZE + SW842_MAX_OUTPUT + SW842_GUARD_SIZE]; + u8 expected_guard[SW842_GUARD_SIZE]; + u8 *output = storage + SW842_GUARD_SIZE; + unsigned int output_len = test_case->output_capacity; + int ret; + + KUNIT_ASSERT_LE(test, test_case->output_capacity, SW842_MAX_OUTPUT); + memset(storage, SW842_GUARD_BYTE, sizeof(storage)); + memset(expected_guard, SW842_GUARD_BYTE, sizeof(expected_guard)); + memset(output, SW842_OUTPUT_POISON, test_case->output_capacity); + + ret = sw842_decompress(test_case->compressed, + test_case->compressed_len, output, &output_len); + + KUNIT_EXPECT_EQ(test, ret, test_case->expected_ret); + /* Every successful case is an exact-fit boundary test. */ + KUNIT_EXPECT_EQ(test, output_len, + test_case->expected_ret ? 0U : test_case->output_capacity); + if (!test_case->expected_ret) + KUNIT_EXPECT_MEMEQ(test, output, test_case->expected_output, + test_case->output_capacity); + KUNIT_EXPECT_MEMEQ(test, storage, expected_guard, SW842_GUARD_SIZE); + KUNIT_EXPECT_MEMEQ(test, output + test_case->output_capacity, + expected_guard, SW842_GUARD_SIZE); +} + +static struct kunit_case sw842_decompress_test_cases[] = { + KUNIT_CASE_PARAM(sw842_decompress_test, sw842_decompress_gen_params), + {} +}; + +static struct kunit_suite sw842_decompress_test_suite = { + .name = "842-decompress", + .test_cases = sw842_decompress_test_cases, +}; + +kunit_test_suite(sw842_decompress_test_suite); + +MODULE_DESCRIPTION("Software 842 decompressor KUnit tests"); +MODULE_LICENSE("GPL"); diff --git a/lib/tests/Makefile b/lib/tests/Makefile index 1a3d39db268f..5f6cf654a128 100644 --- a/lib/tests/Makefile +++ b/lib/tests/Makefile @@ -4,6 +4,7 @@ # KUnit tests CFLAGS_bitfield_kunit.o := $(DISABLE_STRUCTLEAK_PLUGIN) +obj-$(CONFIG_842_DECOMPRESS_KUNIT_TEST) += 842_decompress_kunit.o obj-$(CONFIG_BASE64_KUNIT) += base64_kunit.o obj-$(CONFIG_BITOPS_KUNIT) += bitops_kunit.o obj-$(CONFIG_BITFIELD_KUNIT) += bitfield_kunit.o |
