summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-08-19 17:25:42 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2026-08-19 17:25:42 -0700
commita4ff2be345d0abc943da8dd8da98151843b750dc (patch)
treeda64a462ec69df460299cfec5e0d61534daa8c7c
parenta51ec5e8e5dae80824239f0344210060cb92a4b0 (diff)
parent7537036a2e6fe96f8ed82034f755c54714a0e417 (diff)
Merge tag 'v7.3-p1' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
Pull crypto update from Herbert Xu: "API: - Add af_alg_restrict sysctl and white list - Fix potential suspend/resume races in hwrng Algorithms: - Optimize vli additive operations using compiler builtins in ecc Drivers: - Remove unsafe/deprecated algorithms from qce - Mark qce as BROKEN - Add runtime PM and interconnect bandwidth scaling support to qce - Remove crypto_rng from qcom, sun8i and caam - Fix SG list issues in iaa - Fix SEV init path bugs in ccp" * tag 'v7.3-p1' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6: (122 commits) crypto: lskcipher - propagate errors from unaligned crypt crypto: keembay - use crypto_memneq() to compare CCM AEAD tags crypto: keembay - use crypto_memneq() to compare GCM AEAD tags crypto: sa2ul - use crypto_memneq() to compare AEAD tag hwrng: drivers - use named initializers for acpi_device_id crypto: qce - fix CCM AAD buffer underallocation crypto: iaa - unmap dst before software fallback on decompress crypto: iaa - use bounce buffer for multi-sg decompress input crypto: iaa - avoid counting fallback decompression bytes crypto: iaa - fall back to software for multi-entry scatterlists hwrng: core - Stop/start hwrng_fillfn() kthread before/after suspend-resume crypto: hisilicon/sec2 - fix CCM algorithm long packet failure crypto: eip93 - use struct_size() and flexible array for ring allocation crypto: krb5 - use kfree_sensitive() for derived key buffers crypto: af_alg - Stop after finding name in allowlist crypto: af_alg - Replace 'bool privileged' with flags crypto: af_alg - Make cbc(paes) privileged-only hwrng: imx-rngc - Disable clock on registration failure crypto: qat - remove dead ADF_HEX code crypto: qce - simplify qce_handle_request ...
-rw-r--r--Documentation/ABI/testing/sysfs-firmware-sev-vulnerabilities19
-rw-r--r--Documentation/admin-guide/sysctl/crypto.rst36
-rw-r--r--Documentation/crypto/architecture.rst2
-rw-r--r--Documentation/crypto/userspace-if.rst13
-rw-r--r--Documentation/devicetree/bindings/crypto/qcom,inline-crypto-engine.yaml27
-rw-r--r--Documentation/devicetree/bindings/crypto/qcom,prng.yaml2
-rw-r--r--Documentation/devicetree/bindings/crypto/qcom-qce.yaml1
-rw-r--r--Documentation/devicetree/bindings/rng/inside-secure,safexcel-eip76.yaml2
-rw-r--r--MAINTAINERS2
-rw-r--r--arch/arm/configs/multi_v7_defconfig3
-rw-r--r--arch/arm/configs/qcom_defconfig2
-rw-r--r--arch/arm64/configs/defconfig3
-rw-r--r--arch/powerpc/crypto/aes_cbc.c6
-rw-r--r--crypto/af_alg.c76
-rw-r--r--crypto/algif_aead.c11
-rw-r--r--crypto/algif_hash.c24
-rw-r--r--crypto/algif_rng.c9
-rw-r--r--crypto/algif_skcipher.c23
-rw-r--r--crypto/api.c2
-rw-r--r--crypto/crypto_user.c9
-rw-r--r--crypto/ecc.c98
-rw-r--r--crypto/hctr2.c3
-rw-r--r--crypto/krb5/krb5_api.c8
-rw-r--r--crypto/lrw.c2
-rw-r--r--crypto/lskcipher.c4
-rw-r--r--crypto/xts.c3
-rw-r--r--drivers/char/hw_random/Kconfig13
-rw-r--r--drivers/char/hw_random/Makefile1
-rw-r--r--drivers/char/hw_random/airoha-trng.c4
-rw-r--r--drivers/char/hw_random/atmel-rng.c2
-rw-r--r--drivers/char/hw_random/cctrng.c2
-rw-r--r--drivers/char/hw_random/core.c105
-rw-r--r--drivers/char/hw_random/hisi-trng-v2.c2
-rw-r--r--drivers/char/hw_random/imx-rngc.c6
-rw-r--r--drivers/char/hw_random/jh7110-trng.c3
-rw-r--r--drivers/char/hw_random/ks-sa-rng.c9
-rw-r--r--drivers/char/hw_random/omap-rng.c35
-rw-r--r--drivers/char/hw_random/qcom-rng.c (renamed from drivers/crypto/qcom-rng.c)156
-rw-r--r--drivers/char/hw_random/stm32-rng.c10
-rw-r--r--drivers/char/hw_random/xgene-rng.c4
-rw-r--r--drivers/char/hw_random/xilinx-trng.c32
-rw-r--r--drivers/crypto/Kconfig18
-rw-r--r--drivers/crypto/Makefile1
-rw-r--r--drivers/crypto/allwinner/Kconfig16
-rw-r--r--drivers/crypto/allwinner/sun8i-ce/Makefile1
-rw-r--r--drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c67
-rw-r--r--drivers/crypto/allwinner/sun8i-ce/sun8i-ce-prng.c159
-rw-r--r--drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h29
-rw-r--r--drivers/crypto/allwinner/sun8i-ss/Makefile1
-rw-r--r--drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c49
-rw-r--r--drivers/crypto/allwinner/sun8i-ss/sun8i-ss-prng.c177
-rw-r--r--drivers/crypto/allwinner/sun8i-ss/sun8i-ss.h23
-rw-r--r--drivers/crypto/amcc/crypto4xx_core.c34
-rw-r--r--drivers/crypto/amlogic/amlogic-gxl-core.c4
-rw-r--r--drivers/crypto/aspeed/aspeed-acry.c6
-rw-r--r--drivers/crypto/aspeed/aspeed-hace.c6
-rw-r--r--drivers/crypto/atmel-aes.c4
-rw-r--r--drivers/crypto/atmel-ecc.c66
-rw-r--r--drivers/crypto/atmel-i2c.c5
-rw-r--r--drivers/crypto/atmel-sha.c4
-rw-r--r--drivers/crypto/atmel-sha204a.c16
-rw-r--r--drivers/crypto/atmel-tdes.c72
-rw-r--r--drivers/crypto/bcm/cipher.c4
-rw-r--r--drivers/crypto/caam/Kconfig9
-rw-r--r--drivers/crypto/caam/Makefile1
-rw-r--r--drivers/crypto/caam/caamprng.c241
-rw-r--r--drivers/crypto/caam/intern.h15
-rw-r--r--drivers/crypto/caam/jr.c48
-rw-r--r--drivers/crypto/cavium/nitrox/nitrox_hal.c3
-rw-r--r--drivers/crypto/ccp/ccp-crypto-sha.c2
-rw-r--r--drivers/crypto/ccp/sev-dev.c196
-rw-r--r--drivers/crypto/ccp/sev-dev.h3
-rw-r--r--drivers/crypto/ccree/cc_driver.c4
-rw-r--r--drivers/crypto/gemini/sl3516-ce-cipher.c8
-rw-r--r--drivers/crypto/gemini/sl3516-ce-core.c4
-rw-r--r--drivers/crypto/hisilicon/qm.c5
-rw-r--r--drivers/crypto/hisilicon/sec/sec_drv.c19
-rw-r--r--drivers/crypto/hisilicon/sec2/sec.h3
-rw-r--r--drivers/crypto/hisilicon/sec2/sec_crypto.c37
-rw-r--r--drivers/crypto/img-hash.c4
-rw-r--r--drivers/crypto/inside-secure/eip93/eip93-main.c6
-rw-r--r--drivers/crypto/inside-secure/eip93/eip93-main.h22
-rw-r--r--drivers/crypto/inside-secure/safexcel.c4
-rw-r--r--drivers/crypto/intel/iaa/iaa_crypto_main.c270
-rw-r--r--drivers/crypto/intel/iaa/iaa_crypto_stats.c9
-rw-r--r--drivers/crypto/intel/iaa/iaa_crypto_stats.h2
-rw-r--r--drivers/crypto/intel/ixp4xx/ixp4xx_crypto.c1
-rw-r--r--drivers/crypto/intel/keembay/keembay-ocs-aes-core.c16
-rw-r--r--drivers/crypto/intel/keembay/keembay-ocs-ecc.c5
-rw-r--r--drivers/crypto/intel/keembay/keembay-ocs-hcu-core.c4
-rw-r--r--drivers/crypto/intel/keembay/ocs-aes.c3
-rw-r--r--drivers/crypto/intel/qat/qat_common/adf_aer.c2
-rw-r--r--drivers/crypto/intel/qat/qat_common/adf_cfg.c10
-rw-r--r--drivers/crypto/intel/qat/qat_common/adf_cfg_common.h1
-rw-r--r--drivers/crypto/intel/qat/qat_common/adf_cfg_services.c15
-rw-r--r--drivers/crypto/intel/qat/qat_common/adf_cfg_services.h2
-rw-r--r--drivers/crypto/intel/qat/qat_common/adf_gen2_config.c8
-rw-r--r--drivers/crypto/intel/qat/qat_common/adf_mstate_mgr.c3
-rw-r--r--drivers/crypto/intel/qat/qat_common/adf_sysfs.c2
-rw-r--r--drivers/crypto/intel/qat/qat_common/adf_transport_debug.c3
-rw-r--r--drivers/crypto/intel/qat/qat_common/qat_algs.c1
-rw-r--r--drivers/crypto/intel/qat/qat_common/qat_compression.c3
-rw-r--r--drivers/crypto/marvell/cesa/cesa.c55
-rw-r--r--drivers/crypto/marvell/cesa/cesa.h2
-rw-r--r--drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c28
-rw-r--r--drivers/crypto/marvell/octeontx2/otx2_cpt_mbox_common.c7
-rw-r--r--drivers/crypto/marvell/octeontx2/otx2_cptpf_main.c5
-rw-r--r--drivers/crypto/marvell/octeontx2/otx2_cptpf_ucode.c4
-rw-r--r--drivers/crypto/mxs-dcp.c10
-rw-r--r--drivers/crypto/omap-aes.c88
-rw-r--r--drivers/crypto/omap-des.c4
-rw-r--r--drivers/crypto/omap-sham.c109
-rw-r--r--drivers/crypto/qce/aead.c58
-rw-r--r--drivers/crypto/qce/common.c55
-rw-r--r--drivers/crypto/qce/common.h16
-rw-r--r--drivers/crypto/qce/core.c115
-rw-r--r--drivers/crypto/qce/regs-v5.h4
-rw-r--r--drivers/crypto/qce/sha.c61
-rw-r--r--drivers/crypto/qce/sha.h1
-rw-r--r--drivers/crypto/qce/skcipher.c103
-rw-r--r--drivers/crypto/rockchip/rk3288_crypto.c4
-rw-r--r--drivers/crypto/rockchip/rk3288_crypto_ahash.c7
-rw-r--r--drivers/crypto/sa2ul.c9
-rw-r--r--drivers/crypto/sahara.c3
-rw-r--r--drivers/crypto/stm32/stm32-cryp.c4
-rw-r--r--drivers/crypto/stm32/stm32-hash.c4
-rw-r--r--drivers/crypto/talitos.c30
-rw-r--r--drivers/gpu/drm/ci/arm64.config2
-rw-r--r--include/crypto/aes.h2
-rw-r--r--include/crypto/if_alg.h42
-rw-r--r--include/crypto/internal/ecc.h4
-rw-r--r--include/linux/psp-sev.h51
-rw-r--r--include/linux/rhashtable.h1
-rw-r--r--include/uapi/linux/psp-sfs.h4
-rw-r--r--lib/rhashtable.c2
135 files changed, 1405 insertions, 2019 deletions
diff --git a/Documentation/ABI/testing/sysfs-firmware-sev-vulnerabilities b/Documentation/ABI/testing/sysfs-firmware-sev-vulnerabilities
new file mode 100644
index 000000000000..964362558bb2
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-firmware-sev-vulnerabilities
@@ -0,0 +1,19 @@
+What: /sys/firmware/sev/vulnerabilities/supported_mitigations
+Date: June 2026
+Contact: linux-crypto@vger.kernel.org
+Description:
+ Read-only interface that reports the vector of SEV-SNP
+ firmware vulnerability mitigations supported by the firmware.
+
+What: /sys/firmware/sev/vulnerabilities/verified_mitigations
+Date: June 2026
+Contact: linux-crypto@vger.kernel.org
+Description:
+ Read/write interface that reports the vector of SEV-SNP
+ firmware vulnerability mitigations already verified by the
+ firmware. Writing a vector value requests the firmware to
+ VERIFY the corresponding mitigation bit(s).
+
+ The list of supported mitigations and the meaning of each
+ vector bit are both platform- and bug-specific and are
+ published as part of the AMD Security Bulletin.
diff --git a/Documentation/admin-guide/sysctl/crypto.rst b/Documentation/admin-guide/sysctl/crypto.rst
index b707bd314a64..9a1bd53287f4 100644
--- a/Documentation/admin-guide/sysctl/crypto.rst
+++ b/Documentation/admin-guide/sysctl/crypto.rst
@@ -7,6 +7,42 @@ kernel configuration:
.. contents:: :local:
+.. _af_alg_restrict:
+
+af_alg_restrict
+===============
+
+Controls the level of restriction of AF_ALG.
+
+AF_ALG is a deprecated and rarely-used userspace interface that is a
+frequent source of vulnerabilities. It also unnecessarily exposes a
+large number of kernel implementation details. For more information
+about AF_ALG, see :ref:`Documentation/crypto/userspace-if.rst
+<crypto_userspace_interface>`.
+
+Starting in Linux v7.3, AF_ALG supports only a limited set of
+algorithms by default. This sysctl allows the system administrator to
+remove this restriction when needed for compatibility reasons, or to
+go further and disable AF_ALG entirely. The default value is 1.
+
+=== ==================================================================
+0 AF_ALG is unrestricted.
+
+1 AF_ALG is supported with a limited list of algorithms. The list
+ is designed for compatibility with known users such as iwd and
+ bluez that haven't yet been fixed to use userspace crypto code.
+
+ Specifically, there is an allowlist for unprivileged processes
+ and a somewhat longer allowlist for processes that hold
+ CAP_SYS_ADMIN or CAP_NET_ADMIN in the initial user namespace.
+
+ Attempts to bind() an AF_ALG socket with a disallowed algorithm
+ fail with ENOENT.
+
+2 AF_ALG is completely disabled. Attempts to create an AF_ALG
+ socket fail with EAFNOSUPPORT.
+=== ==================================================================
+
fips_enabled
============
diff --git a/Documentation/crypto/architecture.rst b/Documentation/crypto/architecture.rst
index 249b54d0849f..ec2e99d99aff 100644
--- a/Documentation/crypto/architecture.rst
+++ b/Documentation/crypto/architecture.rst
@@ -95,7 +95,7 @@ additional templates may enclose other templates, such as
::
- template1(template2(single block cipher)))
+ template1(template2(single block cipher))
The kernel crypto API may provide multiple implementations of a template
diff --git a/Documentation/crypto/userspace-if.rst b/Documentation/crypto/userspace-if.rst
index ab93300c8e04..d6194346e366 100644
--- a/Documentation/crypto/userspace-if.rst
+++ b/Documentation/crypto/userspace-if.rst
@@ -1,3 +1,5 @@
+.. _crypto_userspace_interface:
+
User Space Interface
====================
@@ -12,9 +14,14 @@ AF_ALG is insecure and is deprecated. Originally added to the kernel in 2010,
most kernel developers now consider it to be a mistake. Support for hardware
accelerators, which was the original purpose of AF_ALG, has been removed.
-AF_ALG continues to be supported only for backwards compatibility. On systems
-where no programs using AF_ALG remain, the support for it should be disabled by
-disabling ``CONFIG_CRYPTO_USER_API_*``.
+AF_ALG continues to be supported only for backwards compatibility.
+
+Starting in Linux v7.3, the set of algorithms supported by AF_ALG is limited by
+default. See :ref:`/proc/sys/crypto/af_alg_restrict <af_alg_restrict>`.
+
+On systems where no programs using AF_ALG remain, the support for it should be
+disabled entirely by setting ``/proc/sys/crypto/af_alg_restrict`` to 2 or by
+disabling ``CONFIG_CRYPTO_USER_API_*`` in the kernel configuration.
Deprecation
-----------
diff --git a/Documentation/devicetree/bindings/crypto/qcom,inline-crypto-engine.yaml b/Documentation/devicetree/bindings/crypto/qcom,inline-crypto-engine.yaml
index db895c50e2d2..23bf98c2b9fa 100644
--- a/Documentation/devicetree/bindings/crypto/qcom,inline-crypto-engine.yaml
+++ b/Documentation/devicetree/bindings/crypto/qcom,inline-crypto-engine.yaml
@@ -16,15 +16,19 @@ properties:
- qcom,eliza-inline-crypto-engine
- qcom,hawi-inline-crypto-engine
- qcom,kaanapali-inline-crypto-engine
+ - qcom,maili-inline-crypto-engine
- qcom,milos-inline-crypto-engine
+ - qcom,nord-inline-crypto-engine
- qcom,qcs8300-inline-crypto-engine
- qcom,sa8775p-inline-crypto-engine
- qcom,sc7180-inline-crypto-engine
- qcom,sc7280-inline-crypto-engine
+ - qcom,shikra-inline-crypto-engine
- qcom,sm8450-inline-crypto-engine
- qcom,sm8550-inline-crypto-engine
- qcom,sm8650-inline-crypto-engine
- qcom,sm8750-inline-crypto-engine
+ - qcom,x1e80100-inline-crypto-engine
- const: qcom,inline-crypto-engine
reg:
@@ -55,14 +59,25 @@ required:
additionalProperties: false
+# Do not extend the list.
+# Legacy SoCs are allowed for single clock.
+# New SoCs must provide both clocks and power domains.
allOf:
- if:
- properties:
- compatible:
- contains:
- enum:
- - qcom,eliza-inline-crypto-engine
- - qcom,milos-inline-crypto-engine
+ not:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - qcom,kaanapali-inline-crypto-engine
+ - qcom,qcs8300-inline-crypto-engine
+ - qcom,sa8775p-inline-crypto-engine
+ - qcom,sc7180-inline-crypto-engine
+ - qcom,sc7280-inline-crypto-engine
+ - qcom,sm8450-inline-crypto-engine
+ - qcom,sm8550-inline-crypto-engine
+ - qcom,sm8650-inline-crypto-engine
+ - qcom,sm8750-inline-crypto-engine
then:
required:
diff --git a/Documentation/devicetree/bindings/crypto/qcom,prng.yaml b/Documentation/devicetree/bindings/crypto/qcom,prng.yaml
index dc270c8aedf3..de323969fe64 100644
--- a/Documentation/devicetree/bindings/crypto/qcom,prng.yaml
+++ b/Documentation/devicetree/bindings/crypto/qcom,prng.yaml
@@ -23,6 +23,7 @@ properties:
- qcom,ipq5424-trng
- qcom,ipq9574-trng
- qcom,kaanapali-trng
+ - qcom,maili-trng
- qcom,milos-trng
- qcom,nord-trng
- qcom,qcs615-trng
@@ -30,6 +31,7 @@ properties:
- qcom,sa8255p-trng
- qcom,sa8775p-trng
- qcom,sc7280-trng
+ - qcom,shikra-trng
- qcom,sm8450-trng
- qcom,sm8550-trng
- qcom,sm8650-trng
diff --git a/Documentation/devicetree/bindings/crypto/qcom-qce.yaml b/Documentation/devicetree/bindings/crypto/qcom-qce.yaml
index 08febd66c22b..5a653757ee75 100644
--- a/Documentation/devicetree/bindings/crypto/qcom-qce.yaml
+++ b/Documentation/devicetree/bindings/crypto/qcom-qce.yaml
@@ -54,6 +54,7 @@ properties:
- qcom,qcs8300-qce
- qcom,sa8775p-qce
- qcom,sc7280-qce
+ - qcom,shikra-qce
- qcom,sm6350-qce
- qcom,sm8250-qce
- qcom,sm8350-qce
diff --git a/Documentation/devicetree/bindings/rng/inside-secure,safexcel-eip76.yaml b/Documentation/devicetree/bindings/rng/inside-secure,safexcel-eip76.yaml
index f501fc7691c6..92d906998211 100644
--- a/Documentation/devicetree/bindings/rng/inside-secure,safexcel-eip76.yaml
+++ b/Documentation/devicetree/bindings/rng/inside-secure,safexcel-eip76.yaml
@@ -4,7 +4,7 @@
$id: http://devicetree.org/schemas/rng/inside-secure,safexcel-eip76.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
-title: Inside-Secure HWRNG Module
+title: Inside-Secure SafeXcel EIP-76 HWRNG Module
maintainers:
- Jayesh Choudhary <j-choudhary@ti.com>
diff --git a/MAINTAINERS b/MAINTAINERS
index d2b7ed20b247..040df7bfb24f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11848,7 +11848,7 @@ W: http://www.hisilicon.com
F: drivers/spi/spi-hisi-sfc-v3xx.c
HISILICON ZIP Controller DRIVER
-M: Yang Shen <shenyang39@huawei.com>
+M: Chenghai Huang<huangchenghai2@huawei.com>
M: Zhou Wang <wangzhou1@hisilicon.com>
L: linux-crypto@vger.kernel.org
S: Maintained
diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index 6131cec01b0c..f9b8dbf9318c 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -407,6 +407,7 @@ CONFIG_ASPEED_KCS_IPMI_BMC=m
CONFIG_ASPEED_BT_IPMI_BMC=m
CONFIG_HW_RANDOM=y
CONFIG_HW_RANDOM_ST=y
+CONFIG_HW_RANDOM_QCOM=m
CONFIG_TCG_TPM=m
CONFIG_TCG_TIS_I2C_INFINEON=m
CONFIG_I2C_CHARDEV=y
@@ -1322,8 +1323,6 @@ CONFIG_CRYPTO_DEV_ATMEL_AES=m
CONFIG_CRYPTO_DEV_ATMEL_TDES=m
CONFIG_CRYPTO_DEV_ATMEL_SHA=m
CONFIG_CRYPTO_DEV_MARVELL_CESA=m
-CONFIG_CRYPTO_DEV_QCE=m
-CONFIG_CRYPTO_DEV_QCOM_RNG=m
CONFIG_CRYPTO_DEV_ROCKCHIP=m
CONFIG_CRYPTO_DEV_STM32_HASH=m
CONFIG_CRYPTO_DEV_STM32_CRYP=m
diff --git a/arch/arm/configs/qcom_defconfig b/arch/arm/configs/qcom_defconfig
index 03309b89ea4c..df0a0ce5b097 100644
--- a/arch/arm/configs/qcom_defconfig
+++ b/arch/arm/configs/qcom_defconfig
@@ -117,6 +117,7 @@ CONFIG_SERIAL_MSM=y
CONFIG_SERIAL_MSM_CONSOLE=y
CONFIG_SERIAL_DEV_BUS=y
CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_QCOM=m
CONFIG_I2C=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_QUP=y
@@ -296,7 +297,6 @@ CONFIG_CRYPTO_USER_API_HASH=m
CONFIG_CRYPTO_USER_API_SKCIPHER=m
CONFIG_CRYPTO_USER_API_RNG=m
CONFIG_CRYPTO_USER_API_AEAD=m
-CONFIG_CRYPTO_DEV_QCOM_RNG=m
CONFIG_DMA_CMA=y
CONFIG_CMA_SIZE_MBYTES=64
CONFIG_PRINTK_TIME=y
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 7f24c9559553..6ec8d3a69c98 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -603,6 +603,7 @@ CONFIG_HW_RANDOM=y
CONFIG_HW_RANDOM_VIRTIO=y
CONFIG_HW_RANDOM_HISI_TRNG=m
CONFIG_HW_RANDOM_XILINX=m
+CONFIG_HW_RANDOM_QCOM=m
CONFIG_TCG_TPM=y
CONFIG_TCG_TIS=m
CONFIG_TCG_TIS_SPI=m
@@ -1948,8 +1949,6 @@ CONFIG_CRYPTO_AES_ARM64_CE_CCM=y
CONFIG_CRYPTO_DEV_SUN8I_CE=m
CONFIG_CRYPTO_DEV_FSL_CAAM=m
CONFIG_CRYPTO_DEV_FSL_DPAA2_CAAM=m
-CONFIG_CRYPTO_DEV_QCE=m
-CONFIG_CRYPTO_DEV_QCOM_RNG=m
CONFIG_CRYPTO_DEV_TEGRA=m
CONFIG_CRYPTO_DEV_ZYNQMP_AES=m
CONFIG_CRYPTO_DEV_ZYNQMP_SHA3=m
diff --git a/arch/powerpc/crypto/aes_cbc.c b/arch/powerpc/crypto/aes_cbc.c
index 4a9f285f0970..9c271b4642c8 100644
--- a/arch/powerpc/crypto/aes_cbc.c
+++ b/arch/powerpc/crypto/aes_cbc.c
@@ -72,7 +72,7 @@ static int p8_aes_cbc_setkey(struct crypto_skcipher *tfm, const u8 *key,
return ret ? -EINVAL : 0;
}
-static int p8_aes_cbc_crypt(struct skcipher_request *req, int enc)
+static int p8_aes_cbc_crypt(struct skcipher_request *req, bool enc)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
const struct p8_aes_cbc_ctx *ctx = crypto_skcipher_ctx(tfm);
@@ -110,12 +110,12 @@ static int p8_aes_cbc_crypt(struct skcipher_request *req, int enc)
static int p8_aes_cbc_encrypt(struct skcipher_request *req)
{
- return p8_aes_cbc_crypt(req, 1);
+ return p8_aes_cbc_crypt(req, true);
}
static int p8_aes_cbc_decrypt(struct skcipher_request *req)
{
- return p8_aes_cbc_crypt(req, 0);
+ return p8_aes_cbc_crypt(req, false);
}
struct skcipher_alg p8_aes_cbc_alg = {
diff --git a/crypto/af_alg.c b/crypto/af_alg.c
index cce000e8590e..ab84c4488a15 100644
--- a/crypto/af_alg.c
+++ b/crypto/af_alg.c
@@ -8,6 +8,7 @@
*/
#include <linux/atomic.h>
+#include <linux/capability.h>
#include <crypto/if_alg.h>
#include <linux/crypto.h>
#include <linux/init.h>
@@ -22,10 +23,28 @@
#include <linux/sched/signal.h>
#include <linux/security.h>
#include <linux/string.h>
+#include <linux/sysctl.h>
+#include <linux/user_namespace.h>
#include <keys/user-type.h>
#include <keys/trusted-type.h>
#include <keys/encrypted-type.h>
+static int af_alg_restrict = 1;
+
+static const struct ctl_table af_alg_table[] = {
+ {
+ .procname = "af_alg_restrict",
+ .data = &af_alg_restrict,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_dointvec_minmax,
+ .extra1 = SYSCTL_ZERO,
+ .extra2 = SYSCTL_TWO,
+ },
+};
+
+static struct ctl_table_header *af_alg_header;
+
struct alg_type_list {
const struct af_alg_type *type;
struct list_head list;
@@ -110,6 +129,43 @@ int af_alg_unregister_type(const struct af_alg_type *type)
}
EXPORT_SYMBOL_GPL(af_alg_unregister_type);
+static bool af_alg_capable(void)
+{
+ return ns_capable_noaudit(&init_user_ns, CAP_NET_ADMIN) ||
+ capable(CAP_SYS_ADMIN);
+}
+
+int af_alg_check_restriction(const char *name,
+ const struct af_alg_allowlist_entry allowlist[])
+{
+ int level = READ_ONCE(af_alg_restrict);
+
+ if (level == 0)
+ return 0;
+ if (level == 1) {
+ for (const struct af_alg_allowlist_entry *ent = allowlist;
+ ent->name; ent++) {
+ if (strcmp(name, ent->name) == 0) {
+ if ((ent->flags & AF_ALG_UNPRIVILEGED) ||
+ af_alg_capable())
+ return 0;
+ /* List contains at most one entry per name. */
+ break;
+ }
+ }
+ }
+ /*
+ * Use -ENOENT (the error code for "algorithm not found") instead of
+ * -EACCES or -EPERM, for the highest chance of correctly triggering
+ * fallback code paths in userspace programs.
+ *
+ * Don't log a warning, since it would be noisy. iwd tries to bind a
+ * bunch of algorithms that it never uses.
+ */
+ return -ENOENT;
+}
+EXPORT_SYMBOL_GPL(af_alg_check_restriction);
+
static void alg_do_release(const struct af_alg_type *type, void *private)
{
if (!type)
@@ -506,6 +562,9 @@ static int alg_create(struct net *net, struct socket *sock, int protocol,
struct sock *sk;
int err;
+ if (READ_ONCE(af_alg_restrict) == 2)
+ return -EAFNOSUPPORT;
+
if (sock->type != SOCK_SEQPACKET)
return -ESOCKTNOSUPPORT;
if (protocol != 0)
@@ -1222,27 +1281,32 @@ EXPORT_SYMBOL_GPL(af_alg_get_rsgl);
static int __init af_alg_init(void)
{
- int err = proto_register(&alg_proto, 0);
+ int err;
+
+ af_alg_header = register_sysctl("crypto", af_alg_table);
+ err = proto_register(&alg_proto, 0);
if (err)
- goto out;
+ goto out_unregister_sysctl;
err = sock_register(&alg_family);
- if (err != 0)
+ if (err)
goto out_unregister_proto;
-out:
- return err;
+ return 0;
out_unregister_proto:
proto_unregister(&alg_proto);
- goto out;
+out_unregister_sysctl:
+ unregister_sysctl_table(af_alg_header);
+ return err;
}
static void __exit af_alg_exit(void)
{
sock_unregister(PF_ALG);
proto_unregister(&alg_proto);
+ unregister_sysctl_table(af_alg_header);
}
module_init(af_alg_init);
diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c
index 787aac8aeb24..5574e2d70539 100644
--- a/crypto/algif_aead.c
+++ b/crypto/algif_aead.c
@@ -34,6 +34,11 @@
#include <linux/net.h>
#include <net/sock.h>
+static const struct af_alg_allowlist_entry aead_allowlist[] = {
+ { "ccm(aes)" }, /* bluez */
+ {},
+};
+
static inline bool aead_sufficient_data(struct sock *sk)
{
struct alg_sock *ask = alg_sk(sk);
@@ -344,6 +349,12 @@ static struct proto_ops algif_aead_ops_nokey = {
static void *aead_bind(const char *name)
{
+ int err;
+
+ err = af_alg_check_restriction(name, aead_allowlist);
+ if (err)
+ return ERR_PTR(err);
+
return crypto_alloc_aead(name, 0, AF_ALG_CRYPTOAPI_MASK);
}
diff --git a/crypto/algif_hash.c b/crypto/algif_hash.c
index 5452ad6c1506..6e8b5fb82a7f 100644
--- a/crypto/algif_hash.c
+++ b/crypto/algif_hash.c
@@ -16,6 +16,24 @@
#include <linux/net.h>
#include <net/sock.h>
+static const struct af_alg_allowlist_entry hash_allowlist[] = {
+ { "cmac(aes)" }, /* iwd, bluez */
+ { "hmac(md5)" }, /* iwd */
+ { "hmac(sha1)" }, /* iwd */
+ { "hmac(sha224)" }, /* iwd */
+ { "hmac(sha256)" }, /* iwd */
+ { "hmac(sha384)" }, /* iwd */
+ { "hmac(sha512)" }, /* iwd, sha512hmac */
+ { "md4" }, /* iwd */
+ { "md5" }, /* iwd */
+ { "sha1", AF_ALG_UNPRIVILEGED }, /* iwd, iproute2 < 7.0 */
+ { "sha224" }, /* iwd */
+ { "sha256" }, /* iwd */
+ { "sha384" }, /* iwd */
+ { "sha512" }, /* iwd */
+ {},
+};
+
struct hash_ctx {
struct af_alg_sgl sgl;
@@ -382,6 +400,12 @@ static struct proto_ops algif_hash_ops_nokey = {
static void *hash_bind(const char *name)
{
+ int err;
+
+ err = af_alg_check_restriction(name, hash_allowlist);
+ if (err)
+ return ERR_PTR(err);
+
return crypto_alloc_ahash(name, 0, AF_ALG_CRYPTOAPI_MASK);
}
diff --git a/crypto/algif_rng.c b/crypto/algif_rng.c
index 4dfe7899f8fa..bd522915d56d 100644
--- a/crypto/algif_rng.c
+++ b/crypto/algif_rng.c
@@ -50,6 +50,10 @@ MODULE_LICENSE("GPL");
MODULE_AUTHOR("Stephan Mueller <smueller@chronox.de>");
MODULE_DESCRIPTION("User-space interface for random number generators");
+static const struct af_alg_allowlist_entry rng_allowlist[] = {
+ {},
+};
+
struct rng_ctx {
#define MAXSIZE 128
unsigned int len;
@@ -201,6 +205,11 @@ static void *rng_bind(const char *name)
{
struct rng_parent_ctx *pctx;
struct crypto_rng *rng;
+ int err;
+
+ err = af_alg_check_restriction(name, rng_allowlist);
+ if (err)
+ return ERR_PTR(err);
pctx = kzalloc_obj(*pctx);
if (!pctx)
diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c
index 035fed7db81f..1e61fe6e24b9 100644
--- a/crypto/algif_skcipher.c
+++ b/crypto/algif_skcipher.c
@@ -35,6 +35,24 @@
#include <linux/string.h>
#include <net/sock.h>
+static const struct af_alg_allowlist_entry skcipher_allowlist[] = {
+ { "adiantum(xchacha12,aes)", AF_ALG_UNPRIVILEGED }, /* cryptsetup */
+ { "adiantum(xchacha20,aes)", AF_ALG_UNPRIVILEGED }, /* cryptsetup */
+ { "cbc(aes)" }, /* iwd */
+ { "cbc(des)" }, /* iwd */
+ { "cbc(des3_ede)" }, /* iwd */
+ { "cbc(paes)" }, /* caam and others */
+ { "ctr(aes)" }, /* iwd */
+ { "ecb(aes)" }, /* iwd, bluez */
+ { "ecb(des)" }, /* iwd */
+ { "hctr2(aes)", AF_ALG_UNPRIVILEGED }, /* cryptsetup */
+ { "xts(aes)", AF_ALG_UNPRIVILEGED }, /* cryptsetup benchmark */
+ { "xts(camellia)", AF_ALG_UNPRIVILEGED }, /* cryptsetup */
+ { "xts(serpent)", AF_ALG_UNPRIVILEGED }, /* cryptsetup */
+ { "xts(twofish)", AF_ALG_UNPRIVILEGED }, /* cryptsetup */
+ {},
+};
+
static int skcipher_sendmsg(struct socket *sock, struct msghdr *msg,
size_t size)
{
@@ -311,6 +329,11 @@ static struct proto_ops algif_skcipher_ops_nokey = {
static void *skcipher_bind(const char *name)
{
u32 mask = AF_ALG_CRYPTOAPI_MASK;
+ int err;
+
+ err = af_alg_check_restriction(name, skcipher_allowlist);
+ if (err)
+ return ERR_PTR(err);
if (strcmp(name, "cbc(paes)") == 0)
mask = 0;
diff --git a/crypto/api.c b/crypto/api.c
index 4349c2caa23a..24227582cfcf 100644
--- a/crypto/api.c
+++ b/crypto/api.c
@@ -116,7 +116,7 @@ struct crypto_larval *crypto_larval_alloc(const char *name, u32 type, u32 mask)
larval->alg.cra_priority = -1;
larval->alg.cra_destroy = crypto_larval_destroy;
- strscpy(larval->alg.cra_name, name, CRYPTO_MAX_ALG_NAME);
+ strscpy(larval->alg.cra_name, name);
init_completion(&larval->completion);
return larval;
diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
index e8b6ae75f31f..d3ccb507153b 100644
--- a/crypto/crypto_user.c
+++ b/crypto/crypto_user.c
@@ -11,6 +11,7 @@
#include <linux/cryptouser.h>
#include <linux/sched.h>
#include <linux/security.h>
+#include <linux/string.h>
#include <net/netlink.h>
#include <net/net_namespace.h>
#include <net/sock.h>
@@ -87,11 +88,9 @@ static int crypto_report_one(struct crypto_alg *alg,
{
memset(ualg, 0, sizeof(*ualg));
- strscpy(ualg->cru_name, alg->cra_name, sizeof(ualg->cru_name));
- strscpy(ualg->cru_driver_name, alg->cra_driver_name,
- sizeof(ualg->cru_driver_name));
- strscpy(ualg->cru_module_name, module_name(alg->cra_module),
- sizeof(ualg->cru_module_name));
+ strscpy(ualg->cru_name, alg->cra_name);
+ strscpy(ualg->cru_driver_name, alg->cra_driver_name);
+ strscpy(ualg->cru_module_name, module_name(alg->cra_module));
ualg->cru_type = 0;
ualg->cru_mask = 0;
diff --git a/crypto/ecc.c b/crypto/ecc.c
index 6eb4d97a5f0d..3250a464b852 100644
--- a/crypto/ecc.c
+++ b/crypto/ecc.c
@@ -279,6 +279,48 @@ static void vli_rshift1(u64 *vli, unsigned int ndigits)
}
}
+#ifdef __has_builtin
+#if __has_builtin(__builtin_addcll)
+#define USE_BUILTIN_ADDC
+#endif
+#endif
+
+/* Computes result = left + right + carry_in and updates carry_out */
+static inline void add_carry(u64 left, u64 right, u64 *result, u64 carry_in,
+ u64 *carry_out)
+{
+#ifdef USE_BUILTIN_ADDC
+ *result = __builtin_addcll(left, right, carry_in, carry_out);
+#else
+ u64 sum1, sum2;
+ u64 c1 = __builtin_uaddll_overflow(left, right, &sum1);
+ u64 c2 = __builtin_uaddll_overflow(sum1, carry_in, &sum2);
+ *result = sum2;
+ *carry_out = c1 | c2;
+#endif
+}
+
+#ifdef __has_builtin
+#if __has_builtin(__builtin_subcll)
+#define USE_BUILTIN_SUBC
+#endif
+#endif
+
+/* Computes result = left - right - borrow_in and updates borrow_out */
+static inline void sub_borrow(u64 left, u64 right, u64 *result, u64 borrow_in,
+ u64 *borrow_out)
+{
+#ifdef USE_BUILTIN_SUBC
+ *result = __builtin_subcll(left, right, borrow_in, borrow_out);
+#else
+ u64 diff1, diff2;
+ u64 b1 = __builtin_usubll_overflow(left, right, &diff1);
+ u64 b2 = __builtin_usubll_overflow(diff1, borrow_in, &diff2);
+ *result = diff2;
+ *borrow_out = b1 | b2;
+#endif
+}
+
/* Computes result = left + right, returning carry. Can modify in place. */
static u64 vli_add(u64 *result, const u64 *left, const u64 *right,
unsigned int ndigits)
@@ -286,15 +328,8 @@ static u64 vli_add(u64 *result, const u64 *left, const u64 *right,
u64 carry = 0;
int i;
- for (i = 0; i < ndigits; i++) {
- u64 sum;
-
- sum = left[i] + right[i] + carry;
- if (sum != left[i])
- carry = (sum < left[i]);
-
- result[i] = sum;
- }
+ for (i = 0; i < ndigits; i++)
+ add_carry(left[i], right[i], &result[i], carry, &carry);
return carry;
}
@@ -303,40 +338,29 @@ static u64 vli_add(u64 *result, const u64 *left, const u64 *right,
static u64 vli_uadd(u64 *result, const u64 *left, u64 right,
unsigned int ndigits)
{
- u64 carry = right;
+ u64 carry;
int i;
- for (i = 0; i < ndigits; i++) {
- u64 sum;
+ if (ndigits == 0)
+ return right;
- sum = left[i] + carry;
- if (sum != left[i])
- carry = (sum < left[i]);
- else
- carry = !!carry;
+ carry = __builtin_uaddll_overflow(left[0], right, &result[0]);
- result[i] = sum;
- }
+ for (i = 1; i < ndigits; i++)
+ carry = __builtin_uaddll_overflow(left[i], carry, &result[i]);
return carry;
}
/* Computes result = left - right, returning borrow. Can modify in place. */
u64 vli_sub(u64 *result, const u64 *left, const u64 *right,
- unsigned int ndigits)
+ unsigned int ndigits)
{
u64 borrow = 0;
int i;
- for (i = 0; i < ndigits; i++) {
- u64 diff;
-
- diff = left[i] - right[i] - borrow;
- if (diff != left[i])
- borrow = (diff > left[i]);
-
- result[i] = diff;
- }
+ for (i = 0; i < ndigits; i++)
+ sub_borrow(left[i], right[i], &result[i], borrow, &borrow);
return borrow;
}
@@ -344,20 +368,18 @@ EXPORT_SYMBOL(vli_sub);
/* Computes result = left - right, returning borrow. Can modify in place. */
static u64 vli_usub(u64 *result, const u64 *left, u64 right,
- unsigned int ndigits)
+ unsigned int ndigits)
{
- u64 borrow = right;
+ u64 borrow;
int i;
- for (i = 0; i < ndigits; i++) {
- u64 diff;
+ if (ndigits == 0)
+ return right;
- diff = left[i] - borrow;
- if (diff != left[i])
- borrow = (diff > left[i]);
+ borrow = __builtin_usubll_overflow(left[0], right, &result[0]);
- result[i] = diff;
- }
+ for (i = 1; i < ndigits; i++)
+ borrow = __builtin_usubll_overflow(left[i], borrow, &result[i]);
return borrow;
}
diff --git a/crypto/hctr2.c b/crypto/hctr2.c
index ad5edf9366ac..cfc2343bcc1c 100644
--- a/crypto/hctr2.c
+++ b/crypto/hctr2.c
@@ -354,8 +354,7 @@ static int hctr2_create_common(struct crypto_template *tmpl, struct rtattr **tb,
err = -EINVAL;
if (strncmp(xctr_alg->base.cra_name, "xctr(", 5))
goto err_free_inst;
- len = strscpy(blockcipher_name, xctr_alg->base.cra_name + 5,
- sizeof(blockcipher_name));
+ len = strscpy(blockcipher_name, xctr_alg->base.cra_name + 5);
if (len < 1)
goto err_free_inst;
if (blockcipher_name[len - 1] != ')')
diff --git a/crypto/krb5/krb5_api.c b/crypto/krb5/krb5_api.c
index 03395b89cc61..b377f4f7558d 100644
--- a/crypto/krb5/krb5_api.c
+++ b/crypto/krb5/krb5_api.c
@@ -263,10 +263,10 @@ struct crypto_aead *crypto_krb5_prepare_encryption(const struct krb5_enctype *kr
goto err;
}
- kfree(keys.data);
+ kfree_sensitive(keys.data);
return ci;
err:
- kfree(keys.data);
+ kfree_sensitive(keys.data);
return ERR_PTR(ret);
}
EXPORT_SYMBOL(crypto_krb5_prepare_encryption);
@@ -333,10 +333,10 @@ struct crypto_shash *crypto_krb5_prepare_checksum(const struct krb5_enctype *krb
goto err;
}
- kfree(keys.data);
+ kfree_sensitive(keys.data);
return ci;
err:
- kfree(keys.data);
+ kfree_sensitive(keys.data);
return ERR_PTR(ret);
}
EXPORT_SYMBOL(crypto_krb5_prepare_checksum);
diff --git a/crypto/lrw.c b/crypto/lrw.c
index aa31ab03a597..e306e85d7ced 100644
--- a/crypto/lrw.c
+++ b/crypto/lrw.c
@@ -359,7 +359,7 @@ static int lrw_create(struct crypto_template *tmpl, struct rtattr **tb)
if (!memcmp(cipher_name, "ecb(", 4)) {
int len;
- len = strscpy(ecb_name, cipher_name + 4, sizeof(ecb_name));
+ len = strscpy(ecb_name, cipher_name + 4);
if (len < 2)
goto err_free_inst;
diff --git a/crypto/lskcipher.c b/crypto/lskcipher.c
index e4328df6e26c..a8b07594005d 100644
--- a/crypto/lskcipher.c
+++ b/crypto/lskcipher.c
@@ -95,7 +95,6 @@ static int crypto_lskcipher_crypt_unaligned(
while (len >= bs) {
unsigned chunk = min((unsigned)PAGE_SIZE, len);
- int err;
if (chunk > cs)
chunk &= ~(cs - 1);
@@ -528,8 +527,7 @@ struct lskcipher_instance *lskcipher_alloc_instance_simple(
int len;
err = -EINVAL;
- len = strscpy(ecb_name, &cipher_alg->co.base.cra_name[4],
- sizeof(ecb_name));
+ len = strscpy(ecb_name, &cipher_alg->co.base.cra_name[4]);
if (len < 2)
goto err_free_inst;
diff --git a/crypto/xts.c b/crypto/xts.c
index ad97c8091582..1dc948745444 100644
--- a/crypto/xts.c
+++ b/crypto/xts.c
@@ -16,6 +16,7 @@
#include <linux/module.h>
#include <linux/scatterlist.h>
#include <linux/slab.h>
+#include <linux/string.h>
#include <crypto/xts.h>
#include <crypto/b128ops.h>
@@ -400,7 +401,7 @@ static int xts_create(struct crypto_template *tmpl, struct rtattr **tb)
if (!memcmp(cipher_name, "ecb(", 4)) {
int len;
- len = strscpy(name, cipher_name + 4, sizeof(name));
+ len = strscpy(name, cipher_name + 4);
if (len < 2)
goto err_free_inst;
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
index a5bcef4a54ee..1bf5e3f8a557 100644
--- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -193,7 +193,7 @@ config HW_RANDOM_IXP4XX
config HW_RANDOM_OMAP
tristate "OMAP Random Number Generator support"
- depends on ARCH_OMAP16XX || ARCH_OMAP2PLUS || ARCH_MVEBU || ARCH_K3 || COMPILE_TEST
+ depends on ARCH_OMAP16XX || ARCH_OMAP2PLUS || ARCH_MVEBU || ARCH_K3 || ARCH_RZN1 || COMPILE_TEST
default HW_RANDOM
help
This driver provides kernel-side support for the Random Number
@@ -636,6 +636,17 @@ config HW_RANDOM_XILINX
To compile this driver as a module, choose M here: the module
will be called xilinx-trng.
+config HW_RANDOM_QCOM
+ tristate "Qualcomm True Random Number Generator Driver"
+ depends on ARCH_QCOM || COMPILE_TEST
+ depends on HW_RANDOM
+ help
+ This driver provides support for the True Random Number
+ Generator hardware found on some Qualcomm SoCs.
+
+ To compile this driver as a module, choose M here. The
+ module will be called qcom-rng. If unsure, say N.
+
endif # HW_RANDOM
config UML_RANDOM
diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile
index 95b5adb49560..8fce2aa6cf7d 100644
--- a/drivers/char/hw_random/Makefile
+++ b/drivers/char/hw_random/Makefile
@@ -54,3 +54,4 @@ obj-$(CONFIG_HW_RANDOM_POLARFIRE_SOC) += mpfs-rng.o
obj-$(CONFIG_HW_RANDOM_ROCKCHIP) += rockchip-rng.o
obj-$(CONFIG_HW_RANDOM_JH7110) += jh7110-trng.o
obj-$(CONFIG_HW_RANDOM_XILINX) += xilinx-trng.o
+obj-$(CONFIG_HW_RANDOM_QCOM) += qcom-rng.o
diff --git a/drivers/char/hw_random/airoha-trng.c b/drivers/char/hw_random/airoha-trng.c
index 076519a2f100..98c131ee9891 100644
--- a/drivers/char/hw_random/airoha-trng.c
+++ b/drivers/char/hw_random/airoha-trng.c
@@ -186,10 +186,8 @@ static int airoha_trng_probe(struct platform_device *pdev)
airoha_trng_irq_mask(trng);
ret = devm_request_irq(&pdev->dev, irq, airoha_trng_irq, 0,
pdev->name, (void *)trng);
- if (ret) {
- dev_err(dev, "Can't get interrupt working.\n");
+ if (ret)
return ret;
- }
init_completion(&trng->rng_op_done);
diff --git a/drivers/char/hw_random/atmel-rng.c b/drivers/char/hw_random/atmel-rng.c
index 4ebbc44fecf0..06e79d516743 100644
--- a/drivers/char/hw_random/atmel-rng.c
+++ b/drivers/char/hw_random/atmel-rng.c
@@ -185,7 +185,7 @@ static int __maybe_unused atmel_trng_runtime_resume(struct device *dev)
return atmel_trng_init(trng);
}
-static const struct dev_pm_ops __maybe_unused atmel_trng_pm_ops = {
+static const struct dev_pm_ops atmel_trng_pm_ops = {
SET_RUNTIME_PM_OPS(atmel_trng_runtime_suspend,
atmel_trng_runtime_resume, NULL)
SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
diff --git a/drivers/char/hw_random/cctrng.c b/drivers/char/hw_random/cctrng.c
index a5be9258037f..a6925211c3b5 100644
--- a/drivers/char/hw_random/cctrng.c
+++ b/drivers/char/hw_random/cctrng.c
@@ -509,7 +509,7 @@ static int cctrng_probe(struct platform_device *pdev)
/* register the driver isr function */
rc = devm_request_irq(dev, irq, cc_isr, IRQF_SHARED, "cctrng", drvdata);
if (rc)
- return dev_err_probe(dev, rc, "Could not register to interrupt %d\n", irq);
+ return rc;
dev_dbg(dev, "Registered to IRQ: %d\n", irq);
/* Clear all pending interrupts */
diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c
index 6931657ad2ca..57eeefe90da9 100644
--- a/drivers/char/hw_random/core.c
+++ b/drivers/char/hw_random/core.c
@@ -17,14 +17,17 @@
#include <linux/hw_random.h>
#include <linux/kernel.h>
#include <linux/kthread.h>
+#include <linux/lockdep.h>
#include <linux/miscdevice.h>
#include <linux/module.h>
+#include <linux/notifier.h>
#include <linux/random.h>
#include <linux/rcupdate.h>
#include <linux/sched.h>
#include <linux/sched/signal.h>
#include <linux/slab.h>
#include <linux/string.h>
+#include <linux/suspend.h>
#include <linux/sysfs.h>
#include <linux/uaccess.h>
#include <linux/workqueue.h>
@@ -45,6 +48,8 @@ static DEFINE_MUTEX(rng_mutex);
static DEFINE_MUTEX(reading_mutex);
static int data_avail;
static u8 *rng_buffer, *rng_fillbuf;
+/* Set to true during suspend-resume by PM notifier, protected by rng_mutex */
+static bool hwrng_fillfn_stopped;
static unsigned short current_quality;
static unsigned short default_quality = 1024; /* default to maximum */
@@ -57,6 +62,8 @@ MODULE_PARM_DESC(default_quality,
static int hwrng_init(struct hwrng *rng);
static int hwrng_fillfn(void *unused);
+static void hwrng_start_hwrng_fillfn(void);
+static void hwrng_stop_hwrng_fillfn(void);
static size_t rng_buffer_size(void)
{
@@ -114,13 +121,7 @@ static int set_current_rng(struct hwrng *rng)
}
/* if necessary, start hwrng thread */
- if (!hwrng_fill) {
- hwrng_fill = kthread_run(hwrng_fillfn, NULL, "hwrng");
- if (IS_ERR(hwrng_fill)) {
- pr_err("hwrng_fill thread creation failed\n");
- hwrng_fill = NULL;
- }
- }
+ hwrng_start_hwrng_fillfn();
return 0;
}
@@ -137,10 +138,7 @@ static void drop_current_rng(void)
RCU_INIT_POINTER(current_rng, NULL);
synchronize_rcu();
- if (hwrng_fill) {
- kthread_stop(hwrng_fill);
- hwrng_fill = NULL;
- }
+ hwrng_stop_hwrng_fillfn();
/* decrease last reference for triggering the cleanup */
kref_put(&rng->ref, cleanup_rng);
@@ -506,6 +504,36 @@ static struct attribute *rng_dev_attrs[] = {
ATTRIBUTE_GROUPS(rng_dev);
+static void hwrng_start_hwrng_fillfn(void)
+{
+ lockdep_assert_held(&rng_mutex);
+
+ /*
+ * PM notifier stopped the hwrng_fillfn kthread, prevent userspace to
+ * restart it until kernel freezes threads.
+ */
+ if (hwrng_fillfn_stopped)
+ return;
+
+ if (!hwrng_fill) {
+ hwrng_fill = kthread_run(hwrng_fillfn, NULL, "hwrng");
+ if (IS_ERR(hwrng_fill)) {
+ pr_err("hwrng_fill thread creation failed\n");
+ hwrng_fill = NULL;
+ }
+ }
+}
+
+static void hwrng_stop_hwrng_fillfn(void)
+{
+ lockdep_assert_held(&rng_mutex);
+
+ if (hwrng_fill) {
+ kthread_stop(hwrng_fill);
+ hwrng_fill = NULL;
+ }
+}
+
static int hwrng_fillfn(void *unused)
{
size_t entropy, entropy_credit = 0; /* in 1/1024 of a bit */
@@ -559,6 +587,37 @@ static int hwrng_fillfn(void *unused)
return 0;
}
+static int hwrng_pm_notifier(struct notifier_block *nb, unsigned long action,
+ void *data)
+{
+ switch (action) {
+ case PM_SUSPEND_PREPARE:
+ case PM_HIBERNATION_PREPARE:
+ case PM_RESTORE_PREPARE:
+ mutex_lock(&rng_mutex);
+ hwrng_stop_hwrng_fillfn();
+ hwrng_fillfn_stopped = true;
+ mutex_unlock(&rng_mutex);
+ break;
+
+ case PM_POST_SUSPEND:
+ case PM_POST_HIBERNATION:
+ case PM_POST_RESTORE:
+ mutex_lock(&rng_mutex);
+ hwrng_fillfn_stopped = false;
+ if (rcu_access_pointer(current_rng))
+ hwrng_start_hwrng_fillfn();
+ mutex_unlock(&rng_mutex);
+ break;
+ }
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block hwrng_pm_nb = {
+ .notifier_call = hwrng_pm_notifier,
+};
+
int hwrng_register(struct hwrng *rng)
{
int err = -EINVAL;
@@ -596,11 +655,13 @@ int hwrng_register(struct hwrng *rng)
*/
err = set_current_rng(rng);
if (err)
- goto out_unlock;
+ goto out_list_del;
}
}
mutex_unlock(&rng_mutex);
return 0;
+out_list_del:
+ list_del_init(&rng->list);
out_unlock:
mutex_unlock(&rng_mutex);
out:
@@ -705,10 +766,20 @@ static int __init hwrng_modinit(void)
}
ret = misc_register(&rng_miscdev);
- if (ret) {
- kfree(rng_fillbuf);
- kfree(rng_buffer);
- }
+ if (ret)
+ goto misc_err;
+
+ ret = register_pm_notifier(&hwrng_pm_nb);
+ if (ret)
+ goto pm_err;
+
+ return 0;
+
+pm_err:
+ misc_deregister(&rng_miscdev);
+misc_err:
+ kfree(rng_fillbuf);
+ kfree(rng_buffer);
return ret;
}
@@ -721,6 +792,8 @@ static void __exit hwrng_modexit(void)
kfree(rng_fillbuf);
mutex_unlock(&rng_mutex);
+ unregister_pm_notifier(&hwrng_pm_nb);
+
misc_deregister(&rng_miscdev);
}
diff --git a/drivers/char/hw_random/hisi-trng-v2.c b/drivers/char/hw_random/hisi-trng-v2.c
index 6584ed051e09..9e0ecea56ad6 100644
--- a/drivers/char/hw_random/hisi-trng-v2.c
+++ b/drivers/char/hw_random/hisi-trng-v2.c
@@ -77,7 +77,7 @@ static int hisi_trng_probe(struct platform_device *pdev)
}
static const struct acpi_device_id hisi_trng_acpi_match[] = {
- { "HISI02B3", 0 },
+ { .id = "HISI02B3" },
{ }
};
MODULE_DEVICE_TABLE(acpi, hisi_trng_acpi_match);
diff --git a/drivers/char/hw_random/imx-rngc.c b/drivers/char/hw_random/imx-rngc.c
index 28c56c2d1bf6..7693328f1056 100644
--- a/drivers/char/hw_random/imx-rngc.c
+++ b/drivers/char/hw_random/imx-rngc.c
@@ -296,7 +296,7 @@ static int __init imx_rngc_probe(struct platform_device *pdev)
irq, imx_rngc_irq, 0, pdev->name, (void *)rngc);
if (ret) {
clk_disable_unprepare(rngc->clk);
- return dev_err_probe(&pdev->dev, ret, "Can't get interrupt working.\n");
+ return ret;
}
if (self_test) {
@@ -313,8 +313,10 @@ static int __init imx_rngc_probe(struct platform_device *pdev)
devm_pm_runtime_enable(&pdev->dev);
ret = devm_hwrng_register(&pdev->dev, &rngc->rng);
- if (ret)
+ if (ret) {
+ clk_disable_unprepare(rngc->clk);
return dev_err_probe(&pdev->dev, ret, "hwrng registration failed\n");
+ }
dev_info(&pdev->dev,
"Freescale RNG%c registered (HW revision %d.%02d)\n",
diff --git a/drivers/char/hw_random/jh7110-trng.c b/drivers/char/hw_random/jh7110-trng.c
index 4712c3c530e4..aee12caab578 100644
--- a/drivers/char/hw_random/jh7110-trng.c
+++ b/drivers/char/hw_random/jh7110-trng.c
@@ -303,8 +303,7 @@ static int starfive_trng_probe(struct platform_device *pdev)
ret = devm_request_irq(&pdev->dev, irq, starfive_trng_irq, 0, pdev->name,
(void *)trng);
if (ret)
- return dev_err_probe(&pdev->dev, ret,
- "Failed to register interrupt handler\n");
+ return ret;
trng->hclk = devm_clk_get(&pdev->dev, "hclk");
if (IS_ERR(trng->hclk))
diff --git a/drivers/char/hw_random/ks-sa-rng.c b/drivers/char/hw_random/ks-sa-rng.c
index 9e408144a10c..4494f1e4ab4d 100644
--- a/drivers/char/hw_random/ks-sa-rng.c
+++ b/drivers/char/hw_random/ks-sa-rng.c
@@ -242,7 +242,14 @@ static int ks_sa_rng_probe(struct platform_device *pdev)
return dev_err_probe(dev, ret, "Failed to enable SA power-domain\n");
}
- return devm_hwrng_register(&pdev->dev, &ks_sa_rng->rng);
+ ret = devm_hwrng_register(dev, &ks_sa_rng->rng);
+ if (ret) {
+ pm_runtime_put_sync(dev);
+ pm_runtime_disable(dev);
+ return ret;
+ }
+
+ return 0;
}
static void ks_sa_rng_remove(struct platform_device *pdev)
diff --git a/drivers/char/hw_random/omap-rng.c b/drivers/char/hw_random/omap-rng.c
index 5e8b50f15db7..9f0545c67774 100644
--- a/drivers/char/hw_random/omap-rng.c
+++ b/drivers/char/hw_random/omap-rng.c
@@ -391,11 +391,8 @@ static int of_get_omap_rng_device_details(struct omap_rng_dev *priv,
err = devm_request_irq(dev, irq, omap4_rng_irq,
IRQF_TRIGGER_NONE, dev_name(dev), priv);
- if (err) {
- dev_err(dev, "unable to request irq %d, err = %d\n",
- irq, err);
+ if (err)
return err;
- }
/*
* On OMAP4, enabling the shutdown_oflo interrupt is
@@ -455,32 +452,40 @@ static int omap_rng_probe(struct platform_device *pdev)
ret = pm_runtime_resume_and_get(&pdev->dev);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to runtime_get device: %d\n", ret);
- goto err_ioremap;
+ goto err_pm_disable;
}
priv->clk = devm_clk_get(&pdev->dev, NULL);
- if (PTR_ERR(priv->clk) == -EPROBE_DEFER)
- return -EPROBE_DEFER;
+ if (PTR_ERR(priv->clk) == -EPROBE_DEFER) {
+ ret = -EPROBE_DEFER;
+ goto err_pm_put;
+ }
if (!IS_ERR(priv->clk)) {
ret = clk_prepare_enable(priv->clk);
if (ret) {
dev_err(&pdev->dev,
"Unable to enable the clk: %d\n", ret);
- goto err_register;
+ goto err_pm_put;
}
+ } else {
+ priv->clk = NULL;
}
priv->clk_reg = devm_clk_get(&pdev->dev, "reg");
- if (PTR_ERR(priv->clk_reg) == -EPROBE_DEFER)
- return -EPROBE_DEFER;
+ if (PTR_ERR(priv->clk_reg) == -EPROBE_DEFER) {
+ ret = -EPROBE_DEFER;
+ goto err_clk;
+ }
if (!IS_ERR(priv->clk_reg)) {
ret = clk_prepare_enable(priv->clk_reg);
if (ret) {
dev_err(&pdev->dev,
"Unable to enable the register clk: %d\n",
ret);
- goto err_register;
+ goto err_clk;
}
+ } else {
+ priv->clk_reg = NULL;
}
ret = (dev->of_node) ? of_get_omap_rng_device_details(priv, pdev) :
@@ -498,12 +503,14 @@ static int omap_rng_probe(struct platform_device *pdev)
return 0;
err_register:
+ clk_disable_unprepare(priv->clk_reg);
+err_clk:
+ clk_disable_unprepare(priv->clk);
+err_pm_put:
priv->base = NULL;
pm_runtime_put_sync(&pdev->dev);
+err_pm_disable:
pm_runtime_disable(&pdev->dev);
-
- clk_disable_unprepare(priv->clk_reg);
- clk_disable_unprepare(priv->clk);
err_ioremap:
dev_err(dev, "initialization failed.\n");
return ret;
diff --git a/drivers/crypto/qcom-rng.c b/drivers/char/hw_random/qcom-rng.c
index 150e5802e351..4d046caafe5b 100644
--- a/drivers/crypto/qcom-rng.c
+++ b/drivers/char/hw_random/qcom-rng.c
@@ -3,10 +3,8 @@
//
// Based on msm-rng.c and downstream driver
-#include <crypto/internal/rng.h>
#include <linux/acpi.h>
#include <linux/clk.h>
-#include <linux/crypto.h>
#include <linux/hw_random.h>
#include <linux/io.h>
#include <linux/iopoll.h>
@@ -32,24 +30,15 @@
#define QCOM_TRNG_QUALITY 1024
struct qcom_rng {
- struct mutex lock;
void __iomem *base;
struct clk *clk;
struct hwrng hwrng;
- struct qcom_rng_match_data *match_data;
-};
-
-struct qcom_rng_ctx {
- struct qcom_rng *rng;
};
struct qcom_rng_match_data {
- bool skip_init;
bool hwrng_support;
};
-static struct qcom_rng *qcom_rng_dev;
-
static int qcom_rng_read(struct qcom_rng *rng, u8 *data, unsigned int max)
{
unsigned int currsize = 0;
@@ -65,8 +54,6 @@ static int qcom_rng_read(struct qcom_rng *rng, u8 *data, unsigned int max)
return ret;
val = readl_relaxed(rng->base + PRNG_DATA_OUT);
- if (!val)
- return -EINVAL;
if ((max - currsize) >= WORD_SZ) {
memcpy(data, &val, WORD_SZ);
@@ -82,35 +69,11 @@ static int qcom_rng_read(struct qcom_rng *rng, u8 *data, unsigned int max)
return currsize;
}
-static int qcom_rng_generate(struct crypto_rng *tfm,
- const u8 *src, unsigned int slen,
- u8 *dstn, unsigned int dlen)
+static int qcom_hwrng_init(struct hwrng *hwrng)
{
- struct qcom_rng_ctx *ctx = crypto_rng_ctx(tfm);
- struct qcom_rng *rng = ctx->rng;
- int ret;
-
- ret = clk_prepare_enable(rng->clk);
- if (ret)
- return ret;
-
- mutex_lock(&rng->lock);
-
- ret = qcom_rng_read(rng, dstn, dlen);
-
- mutex_unlock(&rng->lock);
- clk_disable_unprepare(rng->clk);
-
- if (ret >= 0)
- ret = 0;
-
- return ret;
-}
+ struct qcom_rng *qrng = container_of(hwrng, struct qcom_rng, hwrng);
-static int qcom_rng_seed(struct crypto_rng *tfm, const u8 *seed,
- unsigned int slen)
-{
- return 0;
+ return clk_prepare_enable(qrng->clk);
}
static int qcom_hwrng_read(struct hwrng *hwrng, void *data, size_t max, bool wait)
@@ -120,74 +83,33 @@ static int qcom_hwrng_read(struct hwrng *hwrng, void *data, size_t max, bool wai
return qcom_rng_read(qrng, data, max);
}
-static int qcom_rng_enable(struct qcom_rng *rng)
+static void qcom_hwrng_cleanup(struct hwrng *hwrng)
{
- u32 val;
- int ret;
-
- ret = clk_prepare_enable(rng->clk);
- if (ret)
- return ret;
-
- /* Enable PRNG only if it is not already enabled */
- val = readl_relaxed(rng->base + PRNG_CONFIG);
- if (val & PRNG_CONFIG_HW_ENABLE)
- goto already_enabled;
-
- val = readl_relaxed(rng->base + PRNG_LFSR_CFG);
- val &= ~PRNG_LFSR_CFG_MASK;
- val |= PRNG_LFSR_CFG_CLOCKS;
- writel(val, rng->base + PRNG_LFSR_CFG);
-
- val = readl_relaxed(rng->base + PRNG_CONFIG);
- val |= PRNG_CONFIG_HW_ENABLE;
- writel(val, rng->base + PRNG_CONFIG);
-
-already_enabled:
- clk_disable_unprepare(rng->clk);
-
- return 0;
-}
-
-static int qcom_rng_init(struct crypto_tfm *tfm)
-{
- struct qcom_rng_ctx *ctx = crypto_tfm_ctx(tfm);
-
- ctx->rng = qcom_rng_dev;
-
- if (!ctx->rng->match_data->skip_init)
- return qcom_rng_enable(ctx->rng);
+ struct qcom_rng *qrng = container_of(hwrng, struct qcom_rng, hwrng);
- return 0;
+ clk_disable_unprepare(qrng->clk);
}
-static struct rng_alg qcom_rng_alg = {
- .generate = qcom_rng_generate,
- .seed = qcom_rng_seed,
- .seedsize = 0,
- .base = {
- .cra_name = "stdrng",
- .cra_driver_name = "qcom-rng",
- .cra_flags = CRYPTO_ALG_TYPE_RNG,
- .cra_priority = 300,
- .cra_ctxsize = sizeof(struct qcom_rng_ctx),
- .cra_module = THIS_MODULE,
- .cra_init = qcom_rng_init,
- }
-};
-
static int qcom_rng_probe(struct platform_device *pdev)
{
+ const struct qcom_rng_match_data *match_data;
struct qcom_rng *rng;
int ret;
+ match_data = device_get_match_data(&pdev->dev);
+ if (match_data == NULL || !match_data->hwrng_support) {
+ dev_info(&pdev->dev, "TRNG support not detected\n");
+ /*
+ * In this case the driver does nothing except the dev_info(),
+ * but bind the device anyway to avoid effects on GCC state.
+ */
+ return 0;
+ }
+
rng = devm_kzalloc(&pdev->dev, sizeof(*rng), GFP_KERNEL);
if (!rng)
return -ENOMEM;
- platform_set_drvdata(pdev, rng);
- mutex_init(&rng->lock);
-
rng->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(rng->base))
return PTR_ERR(rng->base);
@@ -196,53 +118,26 @@ static int qcom_rng_probe(struct platform_device *pdev)
if (IS_ERR(rng->clk))
return PTR_ERR(rng->clk);
- rng->match_data = (struct qcom_rng_match_data *)device_get_match_data(&pdev->dev);
-
- qcom_rng_dev = rng;
- ret = crypto_register_rng(&qcom_rng_alg);
- if (ret) {
- dev_err(&pdev->dev, "Register crypto rng failed: %d\n", ret);
- qcom_rng_dev = NULL;
- return ret;
- }
-
- if (rng->match_data->hwrng_support) {
- rng->hwrng.name = "qcom_hwrng";
- rng->hwrng.read = qcom_hwrng_read;
- rng->hwrng.quality = QCOM_TRNG_QUALITY;
- ret = devm_hwrng_register(&pdev->dev, &rng->hwrng);
- if (ret) {
- dev_err(&pdev->dev, "Register hwrng failed: %d\n", ret);
- qcom_rng_dev = NULL;
- goto fail;
- }
- }
-
- return ret;
-fail:
- crypto_unregister_rng(&qcom_rng_alg);
+ rng->hwrng.name = "qcom_hwrng";
+ rng->hwrng.init = qcom_hwrng_init;
+ rng->hwrng.read = qcom_hwrng_read;
+ rng->hwrng.cleanup = qcom_hwrng_cleanup;
+ rng->hwrng.quality = QCOM_TRNG_QUALITY;
+ ret = devm_hwrng_register(&pdev->dev, &rng->hwrng);
+ if (ret)
+ dev_err(&pdev->dev, "Register hwrng failed: %d\n", ret);
return ret;
}
-static void qcom_rng_remove(struct platform_device *pdev)
-{
- crypto_unregister_rng(&qcom_rng_alg);
-
- qcom_rng_dev = NULL;
-}
-
static struct qcom_rng_match_data qcom_prng_match_data = {
- .skip_init = false,
.hwrng_support = false,
};
static struct qcom_rng_match_data qcom_prng_ee_match_data = {
- .skip_init = true,
.hwrng_support = false,
};
static struct qcom_rng_match_data qcom_trng_match_data = {
- .skip_init = true,
.hwrng_support = true,
};
@@ -262,7 +157,6 @@ MODULE_DEVICE_TABLE(of, qcom_rng_of_match);
static struct platform_driver qcom_rng_driver = {
.probe = qcom_rng_probe,
- .remove = qcom_rng_remove,
.driver = {
.name = KBUILD_MODNAME,
.of_match_table = qcom_rng_of_match,
diff --git a/drivers/char/hw_random/stm32-rng.c b/drivers/char/hw_random/stm32-rng.c
index 9a8c00586ab0..f5bfe54c01dc 100644
--- a/drivers/char/hw_random/stm32-rng.c
+++ b/drivers/char/hw_random/stm32-rng.c
@@ -368,11 +368,6 @@ static int stm32_rng_init(struct hwrng *rng)
return 0;
}
-static void stm32_rng_remove(struct platform_device *ofdev)
-{
- pm_runtime_disable(&ofdev->dev);
-}
-
static int __maybe_unused stm32_rng_runtime_suspend(struct device *dev)
{
struct stm32_rng_private *priv = dev_get_drvdata(dev);
@@ -590,7 +585,9 @@ static int stm32_rng_probe(struct platform_device *ofdev)
pm_runtime_set_autosuspend_delay(dev, 100);
pm_runtime_use_autosuspend(dev);
- pm_runtime_enable(dev);
+ ret = devm_pm_runtime_enable(dev);
+ if (ret)
+ return ret;
return devm_hwrng_register(dev, &priv->rng);
}
@@ -602,7 +599,6 @@ static struct platform_driver stm32_rng_driver = {
.of_match_table = stm32_rng_match,
},
.probe = stm32_rng_probe,
- .remove = stm32_rng_remove,
};
module_platform_driver(stm32_rng_driver);
diff --git a/drivers/char/hw_random/xgene-rng.c b/drivers/char/hw_random/xgene-rng.c
index 1f4b95341c2e..5fa6d28c8746 100644
--- a/drivers/char/hw_random/xgene-rng.c
+++ b/drivers/char/hw_random/xgene-rng.c
@@ -296,7 +296,7 @@ static int xgene_rng_init(struct hwrng *rng)
#ifdef CONFIG_ACPI
static const struct acpi_device_id xgene_rng_acpi_match[] = {
- { "APMC0D18", },
+ { .id = "APMC0D18" },
{ }
};
MODULE_DEVICE_TABLE(acpi, xgene_rng_acpi_match);
@@ -336,7 +336,7 @@ static int xgene_rng_probe(struct platform_device *pdev)
rc = devm_request_irq(&pdev->dev, ctx->irq, xgene_rng_irq_handler, 0,
dev_name(&pdev->dev), ctx);
if (rc)
- return dev_err_probe(&pdev->dev, rc, "Could not request RNG alarm IRQ\n");
+ return rc;
/* Enable IP clock */
clk = devm_clk_get_optional_enabled(&pdev->dev, NULL);
diff --git a/drivers/char/hw_random/xilinx-trng.c b/drivers/char/hw_random/xilinx-trng.c
index 0fbc22c38fbc..290bf5bc82db 100644
--- a/drivers/char/hw_random/xilinx-trng.c
+++ b/drivers/char/hw_random/xilinx-trng.c
@@ -86,8 +86,8 @@ static void xtrng_softreset(struct xilinx_rng *rng)
xtrng_readwrite32(rng->rng_base + TRNG_CTRL_OFFSET, TRNG_CTRL_PRNGSRST_MASK, 0);
}
-/* Return no. of bytes read */
-static size_t xtrng_readblock32(void __iomem *rng_base, __be32 *buf, int blocks32, bool wait)
+/* Return no. of bytes read or a negative error before any data is read. */
+static int xtrng_readblock32(void __iomem *rng_base, __be32 *buf, int blocks32, bool wait)
{
int read = 0, ret;
int timeout = 1;
@@ -102,8 +102,11 @@ static size_t xtrng_readblock32(void __iomem *rng_base, __be32 *buf, int blocks3
ret = readl_poll_timeout(rng_base + TRNG_STATUS_OFFSET, val,
(val & TRNG_STATUS_QCNT_MASK) ==
TRNG_STATUS_QCNT_16_BYTES, !!wait, timeout);
- if (ret)
+ if (ret) {
+ if (!read)
+ return ret;
break;
+ }
for (idx = 0; idx < TRNG_READ_4_WORD; idx++) {
*(buf + read) = cpu_to_be32(ioread32(rng_base + TRNG_CORE_OUTPUT_OFFSET));
@@ -118,27 +121,40 @@ static int xtrng_collect_random_data(struct xilinx_rng *rng, u8 *rand_gen_buf,
{
u8 randbuf[TRNG_SEC_STRENGTH_BYTES];
int byteleft, blocks, count = 0;
+ int full_blocks_bytes;
int ret;
byteleft = no_of_random_bytes & (TRNG_SEC_STRENGTH_BYTES - 1);
blocks = no_of_random_bytes >> TRNG_SEC_STRENGTH_SHIFT;
+ full_blocks_bytes = blocks * TRNG_SEC_STRENGTH_BYTES;
xtrng_readwrite32(rng->rng_base + TRNG_CTRL_OFFSET, TRNG_CTRL_PRNGSTART_MASK,
TRNG_CTRL_PRNGSTART_MASK);
if (blocks) {
ret = xtrng_readblock32(rng->rng_base, (__be32 *)rand_gen_buf, blocks, wait);
- if (!ret)
- return 0;
+ if (ret <= 0) {
+ count = ret;
+ goto out_stop;
+ }
count += ret;
+ if (ret < full_blocks_bytes)
+ goto out_stop;
}
if (byteleft) {
ret = xtrng_readblock32(rng->rng_base, (__be32 *)randbuf, 1, wait);
+ if (ret < 0) {
+ if (!count)
+ count = ret;
+ goto out_stop;
+ }
if (!ret)
- return count;
- memcpy(rand_gen_buf + (blocks * TRNG_SEC_STRENGTH_BYTES), randbuf, byteleft);
- count += byteleft;
+ goto out_stop;
+ ret = min(ret, no_of_random_bytes - count);
+ memcpy(rand_gen_buf + count, randbuf, ret);
+ count += ret;
}
+out_stop:
xtrng_readwrite32(rng->rng_base + TRNG_CTRL_OFFSET,
TRNG_CTRL_PRNGMODE_MASK | TRNG_CTRL_PRNGSTART_MASK, 0U);
diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index 216a00bad5d7..0189dfdcbbe1 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -528,13 +528,17 @@ source "drivers/crypto/intel/Kconfig"
config CRYPTO_DEV_QCE
tristate "Qualcomm crypto engine accelerator"
- depends on ARCH_QCOM || COMPILE_TEST
+ depends on (BROKEN && ARCH_QCOM) || COMPILE_TEST
depends on HAS_IOMEM
help
This driver supports Qualcomm crypto engine accelerator
hardware. To compile this driver as a module, choose M here. The
module will be called qcrypto.
+ This driver does not have exclusive access to the
+ hardware, causing races with the secure world. It
+ is also slower than the CPU.
+
config CRYPTO_DEV_QCE_SKCIPHER
bool
depends on CRYPTO_DEV_QCE
@@ -637,18 +641,6 @@ config CRYPTO_DEV_QCE_SW_MAX_LEN
always processed by the software fallback, and all DES requests
are done by the hardware.
-config CRYPTO_DEV_QCOM_RNG
- tristate "Qualcomm Random Number Generator Driver"
- depends on ARCH_QCOM || COMPILE_TEST
- depends on HW_RANDOM
- select CRYPTO_RNG
- help
- This driver provides support for the Random Number
- Generator hardware found on Qualcomm SoCs.
-
- To compile this driver as a module, choose M here. The
- module will be called qcom-rng. If unsure, say N.
-
config CRYPTO_DEV_IMGTEC_HASH
tristate "Imagination Technologies hardware hash accelerator"
depends on MIPS || COMPILE_TEST
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index 5a950c7abc39..2c33b83f3cfa 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -27,7 +27,6 @@ obj-$(CONFIG_CRYPTO_DEV_PADLOCK_AES) += padlock-aes.o
obj-$(CONFIG_CRYPTO_DEV_PADLOCK_SHA) += padlock-sha.o
obj-$(CONFIG_CRYPTO_DEV_PPC4XX) += amcc/
obj-$(CONFIG_CRYPTO_DEV_QCE) += qce/
-obj-$(CONFIG_CRYPTO_DEV_QCOM_RNG) += qcom-rng.o
obj-$(CONFIG_CRYPTO_DEV_ROCKCHIP) += rockchip/
obj-$(CONFIG_CRYPTO_DEV_S5P) += s5p-sss.o
obj-$(CONFIG_CRYPTO_DEV_SA2UL) += sa2ul.o
diff --git a/drivers/crypto/allwinner/Kconfig b/drivers/crypto/allwinner/Kconfig
index 06ea0e9fe6f2..d86ae005fbe2 100644
--- a/drivers/crypto/allwinner/Kconfig
+++ b/drivers/crypto/allwinner/Kconfig
@@ -70,14 +70,6 @@ config CRYPTO_DEV_SUN8I_CE_HASH
help
Say y to enable support for hash algorithms.
-config CRYPTO_DEV_SUN8I_CE_PRNG
- bool "Support for Allwinner Crypto Engine PRNG"
- depends on CRYPTO_DEV_SUN8I_CE
- select CRYPTO_RNG
- help
- Select this option if you want to provide kernel-side support for
- the Pseudo-Random Number Generator found in the Crypto Engine.
-
config CRYPTO_DEV_SUN8I_CE_TRNG
bool "Support for Allwinner Crypto Engine TRNG"
depends on CRYPTO_DEV_SUN8I_CE
@@ -113,14 +105,6 @@ config CRYPTO_DEV_SUN8I_SS_DEBUG
This will create /sys/kernel/debug/sun8i-ss/stats for displaying
the number of requests per flow and per algorithm.
-config CRYPTO_DEV_SUN8I_SS_PRNG
- bool "Support for Allwinner Security System PRNG"
- depends on CRYPTO_DEV_SUN8I_SS
- select CRYPTO_RNG
- help
- Select this option if you want to provide kernel-side support for
- the Pseudo-Random Number Generator found in the Security System.
-
config CRYPTO_DEV_SUN8I_SS_HASH
bool "Enable support for hash on sun8i-ss"
depends on CRYPTO_DEV_SUN8I_SS
diff --git a/drivers/crypto/allwinner/sun8i-ce/Makefile b/drivers/crypto/allwinner/sun8i-ce/Makefile
index 0842eb2d9408..ea708b427e2e 100644
--- a/drivers/crypto/allwinner/sun8i-ce/Makefile
+++ b/drivers/crypto/allwinner/sun8i-ce/Makefile
@@ -1,5 +1,4 @@
obj-$(CONFIG_CRYPTO_DEV_SUN8I_CE) += sun8i-ce.o
sun8i-ce-y += sun8i-ce-core.o sun8i-ce-cipher.o
sun8i-ce-$(CONFIG_CRYPTO_DEV_SUN8I_CE_HASH) += sun8i-ce-hash.o
-sun8i-ce-$(CONFIG_CRYPTO_DEV_SUN8I_CE_PRNG) += sun8i-ce-prng.o
sun8i-ce-$(CONFIG_CRYPTO_DEV_SUN8I_CE_TRNG) += sun8i-ce-trng.o
diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c
index f3b58ed6aed0..21762bd408e5 100644
--- a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c
+++ b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c
@@ -12,7 +12,6 @@
#include <crypto/engine.h>
#include <crypto/internal/hash.h>
-#include <crypto/internal/rng.h>
#include <crypto/internal/skcipher.h>
#include <linux/clk.h>
#include <linux/delay.h>
@@ -49,7 +48,6 @@ static const struct ce_variant ce_h3_variant = {
{ "mod", 50000000, 0 },
},
.esr = ESR_H3,
- .prng = CE_ALG_PRNG,
.trng = CE_ID_NOTSUPP,
};
@@ -66,7 +64,6 @@ static const struct ce_variant ce_h5_variant = {
{ "mod", 300000000, 0 },
},
.esr = ESR_H5,
- .prng = CE_ALG_PRNG,
.trng = CE_ID_NOTSUPP,
};
@@ -80,7 +77,6 @@ static const struct ce_variant ce_h6_variant = {
},
.cipher_t_dlen_in_bytes = true,
.hash_t_dlen_in_bits = true,
- .prng_t_dlen_in_bytes = true,
.trng_t_dlen_in_bytes = true,
.ce_clks = {
{ "bus", 0, 200000000 },
@@ -88,7 +84,6 @@ static const struct ce_variant ce_h6_variant = {
{ "ram", 0, 400000000 },
},
.esr = ESR_H6,
- .prng = CE_ALG_PRNG_V2,
.trng = CE_ALG_TRNG_V2,
};
@@ -102,7 +97,6 @@ static const struct ce_variant ce_h616_variant = {
},
.cipher_t_dlen_in_bytes = true,
.hash_t_dlen_in_bits = true,
- .prng_t_dlen_in_bytes = true,
.trng_t_dlen_in_bytes = true,
.needs_word_addresses = true,
.ce_clks = {
@@ -112,7 +106,6 @@ static const struct ce_variant ce_h616_variant = {
{ "trng", 0, 0 },
},
.esr = ESR_H6,
- .prng = CE_ALG_PRNG_V2,
.trng = CE_ALG_TRNG_V2,
};
@@ -129,7 +122,6 @@ static const struct ce_variant ce_a64_variant = {
{ "mod", 300000000, 0 },
},
.esr = ESR_A64,
- .prng = CE_ALG_PRNG,
.trng = CE_ID_NOTSUPP,
};
@@ -148,7 +140,6 @@ static const struct ce_variant ce_d1_variant = {
{ "trng", 0, 0 },
},
.esr = ESR_D1,
- .prng = CE_ALG_PRNG,
.trng = CE_ALG_TRNG,
};
@@ -165,7 +156,6 @@ static const struct ce_variant ce_r40_variant = {
{ "mod", 300000000, 0 },
},
.esr = ESR_R40,
- .prng = CE_ALG_PRNG,
.trng = CE_ID_NOTSUPP,
};
@@ -614,25 +604,6 @@ static struct sun8i_ce_alg_template ce_algs[] = {
},
},
#endif
-#ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_PRNG
-{
- .type = CRYPTO_ALG_TYPE_RNG,
- .alg.rng = {
- .base = {
- .cra_name = "stdrng",
- .cra_driver_name = "sun8i-ce-prng",
- .cra_priority = 300,
- .cra_ctxsize = sizeof(struct sun8i_ce_rng_tfm_ctx),
- .cra_module = THIS_MODULE,
- .cra_init = sun8i_ce_prng_init,
- .cra_exit = sun8i_ce_prng_exit,
- },
- .generate = sun8i_ce_prng_generate,
- .seed = sun8i_ce_prng_seed,
- .seedsize = PRNG_SEED_SIZE,
- }
-},
-#endif
};
static int sun8i_ce_debugfs_show(struct seq_file *seq, void *v)
@@ -694,14 +665,6 @@ static int sun8i_ce_debugfs_show(struct seq_file *seq, void *v)
ce_algs[i].stat_fb_maxsg);
break;
#endif
-#ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_PRNG
- case CRYPTO_ALG_TYPE_RNG:
- seq_printf(seq, "%s %s reqs=%lu bytes=%lu\n",
- ce_algs[i].alg.rng.base.cra_driver_name,
- ce_algs[i].alg.rng.base.cra_name,
- ce_algs[i].stat_req, ce_algs[i].stat_bytes);
- break;
-#endif
}
}
#if defined(CONFIG_CRYPTO_DEV_SUN8I_CE_TRNG) && \
@@ -931,25 +894,6 @@ static int sun8i_ce_register_algs(struct sun8i_ce_dev *ce)
}
break;
#endif
-#ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_PRNG
- case CRYPTO_ALG_TYPE_RNG:
- if (ce->variant->prng == CE_ID_NOTSUPP) {
- dev_info(ce->dev,
- "DEBUG: Algo of %s not supported\n",
- ce_algs[i].alg.rng.base.cra_name);
- ce_algs[i].ce = NULL;
- break;
- }
- dev_info(ce->dev, "Register %s\n",
- ce_algs[i].alg.rng.base.cra_name);
- err = crypto_register_rng(&ce_algs[i].alg.rng);
- if (err) {
- dev_err(ce->dev, "Fail to register %s\n",
- ce_algs[i].alg.rng.base.cra_name);
- ce_algs[i].ce = NULL;
- }
- break;
-#endif
default:
ce_algs[i].ce = NULL;
dev_err(ce->dev, "ERROR: tried to register an unknown algo\n");
@@ -978,13 +922,6 @@ static void sun8i_ce_unregister_algs(struct sun8i_ce_dev *ce)
crypto_engine_unregister_ahash(&ce_algs[i].alg.hash);
break;
#endif
-#ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_PRNG
- case CRYPTO_ALG_TYPE_RNG:
- dev_info(ce->dev, "Unregister %d %s\n", i,
- ce_algs[i].alg.rng.base.cra_name);
- crypto_unregister_rng(&ce_algs[i].alg.rng);
- break;
-#endif
}
}
}
@@ -1039,10 +976,8 @@ static int sun8i_ce_probe(struct platform_device *pdev)
err = devm_request_irq(&pdev->dev, irq, ce_irq_handler, 0,
"sun8i-ce-ns", ce);
- if (err) {
- dev_err(ce->dev, "Cannot request CryptoEngine Non-secure IRQ (err=%d)\n", err);
+ if (err)
goto error_pm;
- }
err = sun8i_ce_register_algs(ce);
if (err)
diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-prng.c b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-prng.c
deleted file mode 100644
index d0a1ac66738b..000000000000
--- a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-prng.c
+++ /dev/null
@@ -1,159 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * sun8i-ce-prng.c - hardware cryptographic offloader for
- * Allwinner H3/A64/H5/H2+/H6/R40 SoC
- *
- * Copyright (C) 2015-2020 Corentin Labbe <clabbe@baylibre.com>
- *
- * This file handle the PRNG
- *
- * You could find a link for the datasheet in Documentation/arch/arm/sunxi.rst
- */
-#include "sun8i-ce.h"
-#include <linux/dma-mapping.h>
-#include <linux/pm_runtime.h>
-#include <crypto/internal/rng.h>
-
-int sun8i_ce_prng_init(struct crypto_tfm *tfm)
-{
- struct sun8i_ce_rng_tfm_ctx *ctx = crypto_tfm_ctx(tfm);
-
- memset(ctx, 0, sizeof(struct sun8i_ce_rng_tfm_ctx));
- return 0;
-}
-
-void sun8i_ce_prng_exit(struct crypto_tfm *tfm)
-{
- struct sun8i_ce_rng_tfm_ctx *ctx = crypto_tfm_ctx(tfm);
-
- kfree_sensitive(ctx->seed);
- ctx->seed = NULL;
- ctx->slen = 0;
-}
-
-int sun8i_ce_prng_seed(struct crypto_rng *tfm, const u8 *seed,
- unsigned int slen)
-{
- struct sun8i_ce_rng_tfm_ctx *ctx = crypto_rng_ctx(tfm);
-
- if (ctx->seed && ctx->slen != slen) {
- kfree_sensitive(ctx->seed);
- ctx->slen = 0;
- ctx->seed = NULL;
- }
- if (!ctx->seed)
- ctx->seed = kmalloc(slen, GFP_KERNEL | GFP_DMA);
- if (!ctx->seed)
- return -ENOMEM;
-
- memcpy(ctx->seed, seed, slen);
- ctx->slen = slen;
-
- return 0;
-}
-
-int sun8i_ce_prng_generate(struct crypto_rng *tfm, const u8 *src,
- unsigned int slen, u8 *dst, unsigned int dlen)
-{
- struct sun8i_ce_rng_tfm_ctx *ctx = crypto_rng_ctx(tfm);
- struct rng_alg *alg = crypto_rng_alg(tfm);
- struct sun8i_ce_alg_template *algt;
- struct sun8i_ce_dev *ce;
- dma_addr_t dma_iv, dma_dst;
- int err = 0;
- int flow = 3;
- unsigned int todo;
- struct sun8i_ce_flow *chan;
- struct ce_task *cet;
- u32 common, sym;
- void *d;
-
- algt = container_of(alg, struct sun8i_ce_alg_template, alg.rng);
- ce = algt->ce;
-
- if (ctx->slen == 0) {
- dev_err(ce->dev, "not seeded\n");
- return -EINVAL;
- }
-
- /* we want dlen + seedsize rounded up to a multiple of PRNG_DATA_SIZE */
- todo = dlen + ctx->slen + PRNG_DATA_SIZE * 2;
- todo -= todo % PRNG_DATA_SIZE;
-
- d = kzalloc(todo, GFP_KERNEL | GFP_DMA);
- if (!d) {
- err = -ENOMEM;
- goto err_mem;
- }
-
- dev_dbg(ce->dev, "%s PRNG slen=%u dlen=%u todo=%u multi=%u\n", __func__,
- slen, dlen, todo, todo / PRNG_DATA_SIZE);
-
-#ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG
- algt->stat_req++;
- algt->stat_bytes += todo;
-#endif
-
- dma_iv = dma_map_single(ce->dev, ctx->seed, ctx->slen, DMA_TO_DEVICE);
- if (dma_mapping_error(ce->dev, dma_iv)) {
- dev_err(ce->dev, "Cannot DMA MAP IV\n");
- err = -EFAULT;
- goto err_iv;
- }
-
- dma_dst = dma_map_single(ce->dev, d, todo, DMA_FROM_DEVICE);
- if (dma_mapping_error(ce->dev, dma_dst)) {
- dev_err(ce->dev, "Cannot DMA MAP DST\n");
- err = -EFAULT;
- goto err_dst;
- }
-
- err = pm_runtime_resume_and_get(ce->dev);
- if (err < 0)
- goto err_pm;
-
- mutex_lock(&ce->rnglock);
- chan = &ce->chanlist[flow];
-
- cet = &chan->tl[0];
- memset(cet, 0, sizeof(struct ce_task));
-
- cet->t_id = cpu_to_le32(flow);
- common = ce->variant->prng | CE_COMM_INT;
- cet->t_common_ctl = cpu_to_le32(common);
-
- /* recent CE (H6) need length in bytes, in word otherwise */
- if (ce->variant->prng_t_dlen_in_bytes)
- cet->t_dlen = cpu_to_le32(todo);
- else
- cet->t_dlen = cpu_to_le32(todo / 4);
-
- sym = PRNG_LD;
- cet->t_sym_ctl = cpu_to_le32(sym);
- cet->t_asym_ctl = 0;
-
- cet->t_key = desc_addr_val_le32(ce, dma_iv);
- cet->t_iv = desc_addr_val_le32(ce, dma_iv);
-
- cet->t_dst[0].addr = desc_addr_val_le32(ce, dma_dst);
- cet->t_dst[0].len = cpu_to_le32(todo / 4);
-
- err = sun8i_ce_run_task(ce, 3, "PRNG");
- mutex_unlock(&ce->rnglock);
-
- pm_runtime_put(ce->dev);
-
-err_pm:
- dma_unmap_single(ce->dev, dma_dst, todo, DMA_FROM_DEVICE);
-err_dst:
- dma_unmap_single(ce->dev, dma_iv, ctx->slen, DMA_TO_DEVICE);
-
- if (!err) {
- memcpy(dst, d, dlen);
- memcpy(ctx->seed, d + dlen, ctx->slen);
- }
-err_iv:
- kfree_sensitive(d);
-err_mem:
- return err;
-}
diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h
index 71f5a0cd3d45..468d99bf5bf6 100644
--- a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h
+++ b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h
@@ -15,7 +15,6 @@
#include <linux/hw_random.h>
#include <crypto/internal/hash.h>
#include <crypto/md5.h>
-#include <crypto/rng.h>
#include <crypto/sha1.h>
#include <crypto/sha2.h>
@@ -58,9 +57,7 @@
#define CE_ALG_SHA384 20
#define CE_ALG_SHA512 21
#define CE_ALG_TRNG 48
-#define CE_ALG_PRNG 49
#define CE_ALG_TRNG_V2 0x1c
-#define CE_ALG_PRNG_V2 0x1d
/* Used in ce_variant */
#define CE_ID_NOTSUPP 0xFF
@@ -96,10 +93,6 @@
#define ESR_H6 4
#define ESR_D1 5
-#define PRNG_DATA_SIZE (160 / 8)
-#define PRNG_SEED_SIZE DIV_ROUND_UP(175, 8)
-#define PRNG_LD BIT(17)
-
#define CE_DIE_ID_SHIFT 16
#define CE_DIE_ID_MASK 0x07
@@ -136,13 +129,10 @@ struct ce_clock {
* bytes or words
* @hash_t_dlen_in_bytes: Does the request size for hash is in
* bits or words
- * @prng_t_dlen_in_bytes: Does the request size for PRNG is in
- * bytes or words
* @trng_t_dlen_in_bytes: Does the request size for TRNG is in
* bytes or words
* @ce_clks: list of clocks needed by this variant
* @esr: The type of error register
- * @prng: The CE_ALG_XXX value for the PRNG
* @trng: The CE_ALG_XXX value for the TRNG
*/
struct ce_variant {
@@ -151,12 +141,10 @@ struct ce_variant {
u32 op_mode[CE_ID_OP_MAX];
bool cipher_t_dlen_in_bytes;
bool hash_t_dlen_in_bits;
- bool prng_t_dlen_in_bytes;
bool trng_t_dlen_in_bytes;
bool needs_word_addresses;
struct ce_clock ce_clks[CE_MAX_CLOCKS];
int esr;
- unsigned char prng;
unsigned char trng;
};
@@ -328,16 +316,6 @@ struct sun8i_ce_hash_reqctx {
};
/*
- * struct sun8i_ce_prng_ctx - context for PRNG TFM
- * @seed: The seed to use
- * @slen: The size of the seed
- */
-struct sun8i_ce_rng_tfm_ctx {
- void *seed;
- unsigned int slen;
-};
-
-/*
* struct sun8i_ce_alg_template - crypto_alg template
* @type: the CRYPTO_ALG_TYPE for this template
* @ce_algo_id: the CE_ID for this template
@@ -357,7 +335,6 @@ struct sun8i_ce_alg_template {
union {
struct skcipher_engine_alg skcipher;
struct ahash_engine_alg hash;
- struct rng_alg rng;
} alg;
unsigned long stat_req;
unsigned long stat_fb;
@@ -398,11 +375,5 @@ int sun8i_ce_hash_finup(struct ahash_request *areq);
int sun8i_ce_hash_digest(struct ahash_request *areq);
int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq);
-int sun8i_ce_prng_generate(struct crypto_rng *tfm, const u8 *src,
- unsigned int slen, u8 *dst, unsigned int dlen);
-int sun8i_ce_prng_seed(struct crypto_rng *tfm, const u8 *seed, unsigned int slen);
-void sun8i_ce_prng_exit(struct crypto_tfm *tfm);
-int sun8i_ce_prng_init(struct crypto_tfm *tfm);
-
int sun8i_ce_hwrng_register(struct sun8i_ce_dev *ce);
void sun8i_ce_hwrng_unregister(struct sun8i_ce_dev *ce);
diff --git a/drivers/crypto/allwinner/sun8i-ss/Makefile b/drivers/crypto/allwinner/sun8i-ss/Makefile
index aabfd893c817..2d6458a42e58 100644
--- a/drivers/crypto/allwinner/sun8i-ss/Makefile
+++ b/drivers/crypto/allwinner/sun8i-ss/Makefile
@@ -1,4 +1,3 @@
obj-$(CONFIG_CRYPTO_DEV_SUN8I_SS) += sun8i-ss.o
sun8i-ss-y += sun8i-ss-core.o sun8i-ss-cipher.o
-sun8i-ss-$(CONFIG_CRYPTO_DEV_SUN8I_SS_PRNG) += sun8i-ss-prng.o
sun8i-ss-$(CONFIG_CRYPTO_DEV_SUN8I_SS_HASH) += sun8i-ss-hash.o
diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c
index 59c9bc45ec0f..2167dd9f44c7 100644
--- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c
+++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c
@@ -11,7 +11,6 @@
*/
#include <crypto/engine.h>
-#include <crypto/internal/rng.h>
#include <crypto/internal/skcipher.h>
#include <linux/clk.h>
#include <linux/delay.h>
@@ -283,25 +282,6 @@ static struct sun8i_ss_alg_template ss_algs[] = {
.do_one_request = sun8i_ss_handle_cipher_request,
},
},
-#ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_PRNG
-{
- .type = CRYPTO_ALG_TYPE_RNG,
- .alg.rng = {
- .base = {
- .cra_name = "stdrng",
- .cra_driver_name = "sun8i-ss-prng",
- .cra_priority = 300,
- .cra_ctxsize = sizeof(struct sun8i_ss_rng_tfm_ctx),
- .cra_module = THIS_MODULE,
- .cra_init = sun8i_ss_prng_init,
- .cra_exit = sun8i_ss_prng_exit,
- },
- .generate = sun8i_ss_prng_generate,
- .seed = sun8i_ss_prng_seed,
- .seedsize = PRNG_SEED_SIZE,
- }
-},
-#endif
#ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_HASH
{ .type = CRYPTO_ALG_TYPE_AHASH,
.ss_algo_id = SS_ID_HASH_MD5,
@@ -501,14 +481,6 @@ static int sun8i_ss_debugfs_show(struct seq_file *seq, void *v)
seq_printf(seq, "\tFallback due to SG numbers: %lu\n",
ss_algs[i].stat_fb_sgnum);
break;
-#ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_PRNG
- case CRYPTO_ALG_TYPE_RNG:
- seq_printf(seq, "%s %s reqs=%lu tsize=%lu\n",
- ss_algs[i].alg.rng.base.cra_driver_name,
- ss_algs[i].alg.rng.base.cra_name,
- ss_algs[i].stat_req, ss_algs[i].stat_bytes);
- break;
-#endif
#ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_HASH
case CRYPTO_ALG_TYPE_AHASH:
seq_printf(seq, "%s %s reqs=%lu fallback=%lu\n",
@@ -711,16 +683,6 @@ static int sun8i_ss_register_algs(struct sun8i_ss_dev *ss)
return err;
}
break;
-#ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_PRNG
- case CRYPTO_ALG_TYPE_RNG:
- err = crypto_register_rng(&ss_algs[i].alg.rng);
- if (err) {
- dev_err(ss->dev, "Fail to register %s\n",
- ss_algs[i].alg.rng.base.cra_name);
- ss_algs[i].ss = NULL;
- }
- break;
-#endif
#ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_HASH
case CRYPTO_ALG_TYPE_AHASH:
id = ss_algs[i].ss_algo_id;
@@ -764,13 +726,6 @@ static void sun8i_ss_unregister_algs(struct sun8i_ss_dev *ss)
ss_algs[i].alg.skcipher.base.base.cra_name);
crypto_engine_unregister_skcipher(&ss_algs[i].alg.skcipher);
break;
-#ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_PRNG
- case CRYPTO_ALG_TYPE_RNG:
- dev_info(ss->dev, "Unregister %d %s\n", i,
- ss_algs[i].alg.rng.base.cra_name);
- crypto_unregister_rng(&ss_algs[i].alg.rng);
- break;
-#endif
#ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_HASH
case CRYPTO_ALG_TYPE_AHASH:
dev_info(ss->dev, "Unregister %d %s\n", i,
@@ -869,10 +824,8 @@ static int sun8i_ss_probe(struct platform_device *pdev)
goto error_pm;
err = devm_request_irq(&pdev->dev, irq, ss_irq_handler, 0, "sun8i-ss", ss);
- if (err) {
- dev_err(ss->dev, "Cannot request SecuritySystem IRQ (err=%d)\n", err);
+ if (err)
goto error_irq;
- }
err = sun8i_ss_register_algs(ss);
if (err)
diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-prng.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-prng.c
deleted file mode 100644
index a923cfc6553f..000000000000
--- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-prng.c
+++ /dev/null
@@ -1,177 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * sun8i-ss-prng.c - hardware cryptographic offloader for
- * Allwinner A80/A83T SoC
- *
- * Copyright (C) 2015-2020 Corentin Labbe <clabbe@baylibre.com>
- *
- * This file handle the PRNG found in the SS
- *
- * You could find a link for the datasheet in Documentation/arch/arm/sunxi.rst
- */
-#include "sun8i-ss.h"
-#include <linux/dma-mapping.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/pm_runtime.h>
-#include <crypto/internal/rng.h>
-
-int sun8i_ss_prng_seed(struct crypto_rng *tfm, const u8 *seed,
- unsigned int slen)
-{
- struct sun8i_ss_rng_tfm_ctx *ctx = crypto_rng_ctx(tfm);
-
- if (ctx->seed && ctx->slen != slen) {
- kfree_sensitive(ctx->seed);
- ctx->slen = 0;
- ctx->seed = NULL;
- }
- if (!ctx->seed)
- ctx->seed = kmalloc(slen, GFP_KERNEL);
- if (!ctx->seed)
- return -ENOMEM;
-
- memcpy(ctx->seed, seed, slen);
- ctx->slen = slen;
-
- return 0;
-}
-
-int sun8i_ss_prng_init(struct crypto_tfm *tfm)
-{
- struct sun8i_ss_rng_tfm_ctx *ctx = crypto_tfm_ctx(tfm);
-
- memset(ctx, 0, sizeof(struct sun8i_ss_rng_tfm_ctx));
- return 0;
-}
-
-void sun8i_ss_prng_exit(struct crypto_tfm *tfm)
-{
- struct sun8i_ss_rng_tfm_ctx *ctx = crypto_tfm_ctx(tfm);
-
- kfree_sensitive(ctx->seed);
- ctx->seed = NULL;
- ctx->slen = 0;
-}
-
-int sun8i_ss_prng_generate(struct crypto_rng *tfm, const u8 *src,
- unsigned int slen, u8 *dst, unsigned int dlen)
-{
- struct sun8i_ss_rng_tfm_ctx *ctx = crypto_rng_ctx(tfm);
- struct rng_alg *alg = crypto_rng_alg(tfm);
- struct sun8i_ss_alg_template *algt;
- unsigned int todo_with_padding;
- struct sun8i_ss_dev *ss;
- dma_addr_t dma_iv, dma_dst;
- unsigned int todo;
- int err = 0;
- int flow;
- void *d;
- u32 v;
-
- algt = container_of(alg, struct sun8i_ss_alg_template, alg.rng);
- ss = algt->ss;
-
- if (ctx->slen == 0) {
- dev_err(ss->dev, "The PRNG is not seeded\n");
- return -EINVAL;
- }
-
- /* The SS does not give an updated seed, so we need to get a new one.
- * So we will ask for an extra PRNG_SEED_SIZE data.
- * We want dlen + seedsize rounded up to a multiple of PRNG_DATA_SIZE
- */
- todo = dlen + PRNG_SEED_SIZE + PRNG_DATA_SIZE;
- todo -= todo % PRNG_DATA_SIZE;
-
- todo_with_padding = ALIGN(todo, dma_get_cache_alignment());
- if (todo_with_padding < todo || todo < dlen)
- return -EOVERFLOW;
-
- d = kzalloc(todo_with_padding, GFP_KERNEL);
- if (!d)
- return -ENOMEM;
-
- flow = sun8i_ss_get_engine_number(ss);
-
-#ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG
- algt->stat_req++;
- algt->stat_bytes += todo;
-#endif
-
- v = SS_ALG_PRNG | SS_PRNG_CONTINUE | SS_START;
- if (flow)
- v |= SS_FLOW1;
- else
- v |= SS_FLOW0;
-
- dma_iv = dma_map_single(ss->dev, ctx->seed, ctx->slen, DMA_TO_DEVICE);
- if (dma_mapping_error(ss->dev, dma_iv)) {
- dev_err(ss->dev, "Cannot DMA MAP IV\n");
- err = -EFAULT;
- goto err_free;
- }
-
- dma_dst = dma_map_single(ss->dev, d, todo, DMA_FROM_DEVICE);
- if (dma_mapping_error(ss->dev, dma_dst)) {
- dev_err(ss->dev, "Cannot DMA MAP DST\n");
- err = -EFAULT;
- goto err_iv;
- }
-
- err = pm_runtime_resume_and_get(ss->dev);
- if (err < 0)
- goto err_pm;
- err = 0;
-
- mutex_lock(&ss->mlock);
- writel(dma_iv, ss->base + SS_IV_ADR_REG);
- /* the PRNG act badly (failing rngtest) without SS_KEY_ADR_REG set */
- writel(dma_iv, ss->base + SS_KEY_ADR_REG);
- writel(dma_dst, ss->base + SS_DST_ADR_REG);
- writel(todo / 4, ss->base + SS_LEN_ADR_REG);
-
- reinit_completion(&ss->flows[flow].complete);
- ss->flows[flow].status = 0;
- /* Be sure all data is written before enabling the task */
- wmb();
-
- writel(v, ss->base + SS_CTL_REG);
-
- wait_for_completion_interruptible_timeout(&ss->flows[flow].complete,
- msecs_to_jiffies(todo));
- if (ss->flows[flow].status == 0) {
- dev_err(ss->dev, "DMA timeout for PRNG (size=%u)\n", todo);
- err = -EFAULT;
- }
- /* Since cipher and hash use the linux/cryptoengine and that we have
- * a cryptoengine per flow, we are sure that they will issue only one
- * request per flow.
- * Since the cryptoengine wait for completion before submitting a new
- * one, the mlock could be left just after the final writel.
- * But cryptoengine cannot handle crypto_rng, so we need to be sure
- * nothing will use our flow.
- * The easiest way is to grab mlock until the hardware end our requests.
- * We could have used a per flow lock, but this would increase
- * complexity.
- * The drawback is that no request could be handled for the other flow.
- */
- mutex_unlock(&ss->mlock);
-
- pm_runtime_put(ss->dev);
-
-err_pm:
- dma_unmap_single(ss->dev, dma_dst, todo, DMA_FROM_DEVICE);
-err_iv:
- dma_unmap_single(ss->dev, dma_iv, ctx->slen, DMA_TO_DEVICE);
-
- if (!err) {
- memcpy(dst, d, dlen);
- /* Update seed */
- memcpy(ctx->seed, d + dlen, ctx->slen);
- }
-err_free:
- kfree_sensitive(d);
-
- return err;
-}
diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss.h b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss.h
index 3fc86225edaf..289fb22abfa2 100644
--- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss.h
+++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss.h
@@ -8,7 +8,6 @@
#include <crypto/aes.h>
#include <crypto/des.h>
#include <crypto/engine.h>
-#include <crypto/rng.h>
#include <crypto/skcipher.h>
#include <linux/atomic.h>
#include <linux/debugfs.h>
@@ -27,7 +26,6 @@
#define SS_ALG_DES (1 << 2)
#define SS_ALG_3DES (2 << 2)
#define SS_ALG_MD5 (3 << 2)
-#define SS_ALG_PRNG (4 << 2)
#define SS_ALG_SHA1 (6 << 2)
#define SS_ALG_SHA224 (7 << 2)
#define SS_ALG_SHA256 (8 << 2)
@@ -68,8 +66,6 @@
#define SS_FLOW0 BIT(30)
#define SS_FLOW1 BIT(31)
-#define SS_PRNG_CONTINUE BIT(18)
-
#define MAX_SG 8
#define MAXFLOW 2
@@ -79,9 +75,6 @@
#define SS_DIE_ID_SHIFT 20
#define SS_DIE_ID_MASK 0x07
-#define PRNG_DATA_SIZE (160 / 8)
-#define PRNG_SEED_SIZE DIV_ROUND_UP(175, 8)
-
#define MAX_PAD_SIZE 4096
/*
@@ -214,16 +207,6 @@ struct sun8i_cipher_tfm_ctx {
};
/*
- * struct sun8i_ss_prng_ctx - context for PRNG TFM
- * @seed: The seed to use
- * @slen: The size of the seed
- */
-struct sun8i_ss_rng_tfm_ctx {
- void *seed;
- unsigned int slen;
-};
-
-/*
* struct sun8i_ss_hash_tfm_ctx - context for an ahash TFM
* @fallback_tfm: pointer to the fallback TFM
* @ss: pointer to the private data of driver handling this TFM
@@ -274,7 +257,6 @@ struct sun8i_ss_alg_template {
struct sun8i_ss_dev *ss;
union {
struct skcipher_engine_alg skcipher;
- struct rng_alg rng;
struct ahash_engine_alg hash;
} alg;
unsigned long stat_req;
@@ -300,11 +282,6 @@ int sun8i_ss_skencrypt(struct skcipher_request *areq);
int sun8i_ss_get_engine_number(struct sun8i_ss_dev *ss);
int sun8i_ss_run_task(struct sun8i_ss_dev *ss, struct sun8i_cipher_req_ctx *rctx, const char *name);
-int sun8i_ss_prng_generate(struct crypto_rng *tfm, const u8 *src,
- unsigned int slen, u8 *dst, unsigned int dlen);
-int sun8i_ss_prng_seed(struct crypto_rng *tfm, const u8 *seed, unsigned int slen);
-int sun8i_ss_prng_init(struct crypto_tfm *tfm);
-void sun8i_ss_prng_exit(struct crypto_tfm *tfm);
int sun8i_ss_hash_init_tfm(struct crypto_ahash *tfm);
void sun8i_ss_hash_exit_tfm(struct crypto_ahash *tfm);
diff --git a/drivers/crypto/amcc/crypto4xx_core.c b/drivers/crypto/amcc/crypto4xx_core.c
index 001da785af07..fd010bfb7020 100644
--- a/drivers/crypto/amcc/crypto4xx_core.c
+++ b/drivers/crypto/amcc/crypto4xx_core.c
@@ -1251,6 +1251,10 @@ 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);
+
/*
* Older version of 460EX/GT have a hardware bug.
* Hence they do not support H/W based security intr coalescing
@@ -1286,25 +1290,18 @@ static int crypto4xx_probe(struct platform_device *ofdev)
tasklet_init(&core_dev->tasklet, crypto4xx_bh_tasklet_cb,
(unsigned long) dev);
- core_dev->dev->ce_base = devm_platform_ioremap_resource(ofdev, 0);
- if (IS_ERR(core_dev->dev->ce_base)) {
- dev_err(&ofdev->dev, "failed to ioremap resource");
- rc = PTR_ERR(core_dev->dev->ce_base);
- goto err_build_sdr;
- }
-
/* 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_iomap;
+ goto err_tasklet;
}
- rc = devm_request_irq(&ofdev->dev, core_dev->irq,
- is_revb ? crypto4xx_ce_interrupt_handler_revb :
- crypto4xx_ce_interrupt_handler,
- 0, KBUILD_MODNAME, dev);
+ rc = request_irq(core_dev->irq,
+ is_revb ? crypto4xx_ce_interrupt_handler_revb :
+ crypto4xx_ce_interrupt_handler,
+ 0, KBUILD_MODNAME, dev);
if (rc)
- goto err_iomap;
+ goto err_tasklet;
/* need to setup pdr, rdr, gdr and sdr before this */
crypto4xx_hw_init(core_dev->dev);
@@ -1313,12 +1310,14 @@ static int crypto4xx_probe(struct platform_device *ofdev)
rc = crypto4xx_register_alg(core_dev->dev, crypto4xx_alg,
ARRAY_SIZE(crypto4xx_alg));
if (rc)
- goto err_iomap;
+ goto err_irq;
ppc4xx_trng_probe(core_dev);
return 0;
-err_iomap:
+err_irq:
+ free_irq(core_dev->irq, dev);
+err_tasklet:
tasklet_kill(&core_dev->tasklet);
err_build_sdr:
crypto4xx_destroy_sdr(core_dev->dev);
@@ -1334,6 +1333,11 @@ static void crypto4xx_remove(struct platform_device *ofdev)
ppc4xx_trng_remove(core_dev);
+ /*
+ * 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);
tasklet_kill(&core_dev->tasklet);
/* Un-register with Linux CryptoAPI */
crypto4xx_unregister_alg(core_dev->dev);
diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
index 6cb33949915f..169c6eeb51e5 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
@@ -257,10 +257,8 @@ static int meson_crypto_probe(struct platform_device *pdev)
err = devm_request_irq(&pdev->dev, mc->irqs[i], meson_irq_handler, 0,
"gxl-crypto", mc);
- if (err < 0) {
- dev_err(mc->dev, "Cannot request IRQ for flow %d\n", i);
+ if (err < 0)
return err;
- }
}
err = clk_prepare_enable(mc->busclk);
diff --git a/drivers/crypto/aspeed/aspeed-acry.c b/drivers/crypto/aspeed/aspeed-acry.c
index 5993bcba9716..97327ba2c24b 100644
--- a/drivers/crypto/aspeed/aspeed-acry.c
+++ b/drivers/crypto/aspeed/aspeed-acry.c
@@ -728,14 +728,12 @@ static int aspeed_acry_probe(struct platform_device *pdev)
/* Get irq number and register it */
acry_dev->irq = platform_get_irq(pdev, 0);
if (acry_dev->irq < 0)
- return -ENXIO;
+ return acry_dev->irq;
rc = devm_request_irq(dev, acry_dev->irq, aspeed_acry_irq, 0,
dev_name(dev), acry_dev);
- if (rc) {
- dev_err(dev, "Failed to request irq.\n");
+ if (rc)
return rc;
- }
acry_dev->clk = devm_clk_get_enabled(dev, NULL);
if (IS_ERR(acry_dev->clk)) {
diff --git a/drivers/crypto/aspeed/aspeed-hace.c b/drivers/crypto/aspeed/aspeed-hace.c
index 3fe644bfe037..6555d7b2afe5 100644
--- a/drivers/crypto/aspeed/aspeed-hace.c
+++ b/drivers/crypto/aspeed/aspeed-hace.c
@@ -127,14 +127,12 @@ static int aspeed_hace_probe(struct platform_device *pdev)
/* Get irq number and register it */
hace_dev->irq = platform_get_irq(pdev, 0);
if (hace_dev->irq < 0)
- return -ENXIO;
+ return hace_dev->irq;
rc = devm_request_irq(&pdev->dev, hace_dev->irq, aspeed_hace_irq, 0,
dev_name(&pdev->dev), hace_dev);
- if (rc) {
- dev_err(&pdev->dev, "Failed to request interrupt\n");
+ if (rc)
return rc;
- }
/* Get clk and enable it */
hace_dev->clk = devm_clk_get(&pdev->dev, NULL);
diff --git a/drivers/crypto/atmel-aes.c b/drivers/crypto/atmel-aes.c
index f79d7c456546..2f78c29d5042 100644
--- a/drivers/crypto/atmel-aes.c
+++ b/drivers/crypto/atmel-aes.c
@@ -2368,10 +2368,8 @@ static int atmel_aes_probe(struct platform_device *pdev)
err = devm_request_irq(&pdev->dev, aes_dd->irq, atmel_aes_irq,
IRQF_SHARED, "atmel-aes", aes_dd);
- if (err) {
- dev_err(dev, "unable to request aes irq.\n");
+ if (err)
goto err_tasklet_kill;
- }
/* Initializing the clock */
aes_dd->iclk = devm_clk_get_prepared(&pdev->dev, "aes_clk");
diff --git a/drivers/crypto/atmel-ecc.c b/drivers/crypto/atmel-ecc.c
index 9da9dd6585df..075f38a67935 100644
--- a/drivers/crypto/atmel-ecc.c
+++ b/drivers/crypto/atmel-ecc.c
@@ -27,21 +27,18 @@ static struct atmel_ecc_driver_data driver_data;
/**
* struct atmel_ecdh_ctx - transformation context
- * @client : pointer to i2c client device
- * @fallback : used for unsupported curves or when user wants to use its own
- * private key.
- * @public_key : generated when calling set_secret(). It's the responsibility
- * of the user to not call set_secret() while
- * generate_public_key() or compute_shared_secret() are in flight.
- * @curve_id : elliptic curve id
- * @do_fallback: true when the device doesn't support the curve or when the user
- * wants to use its own private key.
+ * @client: I2C client device
+ * @fallback: ECDH fallback used for caller-provided private keys
+ * @public_key: cached public key for the device-generated private key
+ * @do_fallback: true when ECDH operations should use @fallback
+ *
+ * The caller must not invoke set_secret() while generate_public_key()
+ * or compute_shared_secret() are in flight.
*/
struct atmel_ecdh_ctx {
struct i2c_client *client;
struct crypto_kpp *fallback;
const u8 *public_key;
- unsigned int curve_id;
bool do_fallback;
};
@@ -55,7 +52,7 @@ static void atmel_ecdh_done(struct atmel_i2c_work_data *work_data, void *areq,
if (status)
goto free_work_data;
- /* might want less than we've got */
+ /* copy only as much as requested, capped at 32 bytes */
n_sz = min(ATMEL_ECC_NIST_P256_N_SIZE, req->dst_len);
/* copy the shared secret */
@@ -64,15 +61,15 @@ static void atmel_ecdh_done(struct atmel_i2c_work_data *work_data, void *areq,
if (copied != n_sz)
status = -EINVAL;
- /* fall through */
free_work_data:
kfree_sensitive(work_data);
kpp_request_complete(req, status);
}
/*
- * A random private key is generated and stored in the device. The device
- * returns the pair public key.
+ * If no private key is provided, generate one in the device and cache
+ * the corresponding public key. The generated private key never leaves
+ * the device.
*/
static int atmel_ecdh_set_secret(struct crypto_kpp *tfm, const void *buf,
unsigned int len)
@@ -83,10 +80,9 @@ static int atmel_ecdh_set_secret(struct crypto_kpp *tfm, const void *buf,
struct ecdh params;
int ret = -ENOMEM;
- /* free the old public key, if any */
kfree(ctx->public_key);
- /* make sure you don't free the old public key twice */
ctx->public_key = NULL;
+ ctx->do_fallback = false;
if (crypto_ecdh_decode_key(buf, len, &params) < 0) {
dev_err(&ctx->client->dev, "crypto_ecdh_decode_key failed\n");
@@ -94,41 +90,30 @@ static int atmel_ecdh_set_secret(struct crypto_kpp *tfm, const void *buf,
}
if (params.key_size) {
- /* fallback to ecdh software implementation */
- ctx->do_fallback = true;
- return crypto_kpp_set_secret(ctx->fallback, buf, len);
+ ret = crypto_kpp_set_secret(ctx->fallback, buf, len);
+ ctx->do_fallback = !ret;
+ return ret;
}
cmd = kmalloc_obj(*cmd);
if (!cmd)
return -ENOMEM;
- /*
- * The device only supports NIST P256 ECC keys. The public key size will
- * always be the same. Use a macro for the key size to avoid unnecessary
- * computations.
- */
public_key = kmalloc(ATMEL_ECC_PUBKEY_SIZE, GFP_KERNEL);
if (!public_key)
goto free_cmd;
- ctx->do_fallback = false;
-
atmel_i2c_init_genkey_cmd(cmd, DATA_SLOT_2);
ret = atmel_i2c_send_receive(ctx->client, cmd);
- if (ret)
- goto free_public_key;
+ if (ret) {
+ kfree(public_key);
+ goto free_cmd;
+ }
- /* save the public key */
memcpy(public_key, &cmd->data[RSP_DATA_IDX], ATMEL_ECC_PUBKEY_SIZE);
ctx->public_key = public_key;
- kfree(cmd);
- return 0;
-
-free_public_key:
- kfree(public_key);
free_cmd:
kfree(cmd);
return ret;
@@ -139,7 +124,6 @@ static int atmel_ecdh_generate_public_key(struct kpp_request *req)
struct crypto_kpp *tfm = crypto_kpp_reqtfm(req);
struct atmel_ecdh_ctx *ctx = kpp_tfm_ctx(tfm);
size_t copied, nbytes;
- int ret = 0;
if (ctx->do_fallback) {
kpp_request_set_tfm(req, ctx->fallback);
@@ -149,7 +133,7 @@ static int atmel_ecdh_generate_public_key(struct kpp_request *req)
if (!ctx->public_key)
return -EINVAL;
- /* might want less than we've got */
+ /* copy only as much as requested, capped at 64 bytes */
nbytes = min(ATMEL_ECC_PUBKEY_SIZE, req->dst_len);
/* public key was saved at private key generation */
@@ -157,9 +141,9 @@ static int atmel_ecdh_generate_public_key(struct kpp_request *req)
sg_nents_for_len(req->dst, nbytes),
ctx->public_key, nbytes);
if (copied != nbytes)
- ret = -EINVAL;
+ return -EINVAL;
- return ret;
+ return 0;
}
static int atmel_ecdh_compute_shared_secret(struct kpp_request *req)
@@ -175,7 +159,10 @@ static int atmel_ecdh_compute_shared_secret(struct kpp_request *req)
return crypto_kpp_compute_shared_secret(req);
}
- /* must have exactly two points to be on the curve */
+ if (!ctx->public_key)
+ return -EINVAL;
+
+ /* A P-256 public key must contain two 32-byte coordinates */
if (req->src_len != ATMEL_ECC_PUBKEY_SIZE)
return -EINVAL;
@@ -250,7 +237,6 @@ static int atmel_ecdh_init_tfm(struct crypto_kpp *tfm)
struct crypto_kpp *fallback;
struct atmel_ecdh_ctx *ctx = kpp_tfm_ctx(tfm);
- ctx->curve_id = ECC_CURVE_NIST_P256;
ctx->client = atmel_ecc_i2c_client_alloc();
if (IS_ERR(ctx->client)) {
pr_err("tfm - i2c_client binding failed\n");
diff --git a/drivers/crypto/atmel-i2c.c b/drivers/crypto/atmel-i2c.c
index ff19857894d0..24bded47a32b 100644
--- a/drivers/crypto/atmel-i2c.c
+++ b/drivers/crypto/atmel-i2c.c
@@ -138,9 +138,8 @@ int atmel_i2c_init_ecdh_cmd(struct atmel_i2c_cmd *cmd,
cmd->param2 = cpu_to_le16(DATA_SLOT_2);
/*
- * The device only supports NIST P256 ECC keys. The public key size will
- * always be the same. Use a macro for the key size to avoid unnecessary
- * computations.
+ * The device only supports P-256. Its public key is encoded as
+ * two 32-byte coordinates.
*/
copied = sg_copy_to_buffer(pubkey,
sg_nents_for_len(pubkey,
diff --git a/drivers/crypto/atmel-sha.c b/drivers/crypto/atmel-sha.c
index 66323ac63406..48f54b615504 100644
--- a/drivers/crypto/atmel-sha.c
+++ b/drivers/crypto/atmel-sha.c
@@ -2604,10 +2604,8 @@ static int atmel_sha_probe(struct platform_device *pdev)
err = devm_request_irq(&pdev->dev, sha_dd->irq, atmel_sha_irq,
IRQF_SHARED, "atmel-sha", sha_dd);
- if (err) {
- dev_err(dev, "unable to request sha irq.\n");
+ if (err)
goto err_tasklet_kill;
- }
/* Initializing the clock */
sha_dd->iclk = devm_clk_get_prepared(&pdev->dev, "sha_clk");
diff --git a/drivers/crypto/atmel-sha204a.c b/drivers/crypto/atmel-sha204a.c
index 4c9af737b33a..21a84c29c9b7 100644
--- a/drivers/crypto/atmel-sha204a.c
+++ b/drivers/crypto/atmel-sha204a.c
@@ -15,6 +15,7 @@
#include <linux/module.h>
#include <linux/scatterlist.h>
#include <linux/slab.h>
+#include <linux/string.h>
#include <linux/sysfs.h>
#include <linux/workqueue.h>
#include "atmel-i2c.h"
@@ -31,10 +32,14 @@ static void atmel_sha204a_rng_done(struct atmel_i2c_work_data *work_data,
struct atmel_i2c_client_priv *i2c_priv = work_data->ctx;
struct hwrng *rng = areq;
- if (status)
+ if (status) {
dev_warn_ratelimited(&i2c_priv->client->dev,
"i2c transaction failed (%d)\n",
status);
+ kfree_sensitive(work_data);
+ atomic_dec(&i2c_priv->tfm_count);
+ return;
+ }
rng->priv = (unsigned long)work_data;
atomic_dec(&i2c_priv->tfm_count);
@@ -91,12 +96,15 @@ static int atmel_sha204a_rng_read(struct hwrng *rng, void *data, size_t max,
ret = atmel_i2c_send_receive(i2c_priv->client, &cmd);
if (ret)
- return ret;
+ goto out;
max = min(RANDOM_RSP_SIZE - CMD_OVERHEAD_SIZE, max);
memcpy(data, &cmd.data[RSP_DATA_IDX], max);
+ ret = max;
- return max;
+out:
+ memzero_explicit(&cmd, sizeof(cmd));
+ return ret;
}
static int atmel_sha204a_otp_read(struct i2c_client *client, u16 addr, u8 *otp)
@@ -205,7 +213,7 @@ static void atmel_sha204a_remove(struct i2c_client *client)
devm_hwrng_unregister(&client->dev, &i2c_priv->hwrng);
atmel_i2c_flush_queue();
- kfree((void *)i2c_priv->hwrng.priv);
+ kfree_sensitive((void *)i2c_priv->hwrng.priv);
}
static const struct of_device_id atmel_sha204a_dt_ids[] = {
diff --git a/drivers/crypto/atmel-tdes.c b/drivers/crypto/atmel-tdes.c
index 3c0eacacfc87..ffea1db74651 100644
--- a/drivers/crypto/atmel-tdes.c
+++ b/drivers/crypto/atmel-tdes.c
@@ -284,7 +284,6 @@ static int atmel_tdes_write_ctrl(struct atmel_tdes_dev *dd)
static int atmel_tdes_crypt_pdc_stop(struct atmel_tdes_dev *dd)
{
- int err = 0;
size_t count;
atmel_tdes_write(dd, TDES_PTCR, TDES_PTCR_TXTDIS|TDES_PTCR_RXTDIS);
@@ -296,24 +295,23 @@ static int atmel_tdes_crypt_pdc_stop(struct atmel_tdes_dev *dd)
dma_sync_single_for_cpu(dd->dev, dd->dma_addr_out,
dd->dma_size, DMA_FROM_DEVICE);
- /* copy data */
count = atmel_tdes_sg_copy(&dd->out_sg, &dd->out_offset,
dd->buf_out, dd->buflen, dd->dma_size, 1);
if (count != dd->dma_size) {
- err = -EINVAL;
dev_dbg(dd->dev, "not all data converted: %zu\n", count);
+ return -EINVAL;
}
}
- return err;
+ return 0;
}
static int atmel_tdes_buff_init(struct atmel_tdes_dev *dd)
{
int err = -ENOMEM;
- dd->buf_in = (void *)__get_free_pages(GFP_KERNEL, 0);
- dd->buf_out = (void *)__get_free_pages(GFP_KERNEL, 0);
+ 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);
@@ -450,26 +448,19 @@ static int atmel_tdes_crypt_dma(struct atmel_tdes_dev *dd,
static int atmel_tdes_crypt_start(struct atmel_tdes_dev *dd)
{
- int err, fast = 0, in, out;
+ bool fast;
+ int err;
size_t count;
dma_addr_t addr_in, addr_out;
- if ((!dd->in_offset) && (!dd->out_offset)) {
- /* check for alignment */
- in = IS_ALIGNED((u32)dd->in_sg->offset, sizeof(u32)) &&
- IS_ALIGNED(dd->in_sg->length, dd->ctx->block_size);
- out = IS_ALIGNED((u32)dd->out_sg->offset, sizeof(u32)) &&
- IS_ALIGNED(dd->out_sg->length, dd->ctx->block_size);
- fast = in && out;
-
- if (sg_dma_len(dd->in_sg) != sg_dma_len(dd->out_sg))
- fast = 0;
- }
-
+ fast = !dd->in_offset && !dd->out_offset &&
+ dd->in_sg->length == dd->out_sg->length &&
+ IS_ALIGNED(dd->in_sg->offset, sizeof(u32)) &&
+ IS_ALIGNED(dd->out_sg->offset, sizeof(u32)) &&
+ IS_ALIGNED(dd->in_sg->length, dd->ctx->block_size);
- if (fast) {
- count = min_t(size_t, dd->total, sg_dma_len(dd->in_sg));
- count = min_t(size_t, count, sg_dma_len(dd->out_sg));
+ if (fast) {
+ count = min(dd->total, dd->in_sg->length);
err = dma_map_sg(dd->dev, dd->in_sg, 1, DMA_TO_DEVICE);
if (!err) {
@@ -609,28 +600,25 @@ static int atmel_tdes_handle_queue(struct atmel_tdes_dev *dd,
static int atmel_tdes_crypt_dma_stop(struct atmel_tdes_dev *dd)
{
- int err = -EINVAL;
size_t count;
- if (dd->flags & TDES_FLAGS_DMA) {
- err = 0;
- if (dd->flags & TDES_FLAGS_FAST) {
- dma_unmap_sg(dd->dev, dd->out_sg, 1, DMA_FROM_DEVICE);
- dma_unmap_sg(dd->dev, dd->in_sg, 1, DMA_TO_DEVICE);
- } else {
- dma_sync_single_for_cpu(dd->dev, dd->dma_addr_out,
- dd->dma_size, DMA_FROM_DEVICE);
-
- /* copy data */
- count = atmel_tdes_sg_copy(&dd->out_sg, &dd->out_offset,
- dd->buf_out, dd->buflen, dd->dma_size, 1);
- if (count != dd->dma_size) {
- err = -EINVAL;
- dev_dbg(dd->dev, "not all data converted: %zu\n", count);
- }
+ if (dd->flags & TDES_FLAGS_FAST) {
+ dma_unmap_sg(dd->dev, dd->out_sg, 1, DMA_FROM_DEVICE);
+ dma_unmap_sg(dd->dev, dd->in_sg, 1, DMA_TO_DEVICE);
+ } else {
+ dma_sync_single_for_cpu(dd->dev, dd->dma_addr_out, dd->dma_size,
+ DMA_FROM_DEVICE);
+
+ count = atmel_tdes_sg_copy(&dd->out_sg, &dd->out_offset,
+ dd->buf_out, dd->buflen,
+ dd->dma_size, 1);
+ if (count != dd->dma_size) {
+ dev_dbg(dd->dev, "not all data converted: %zu\n", count);
+ return -EINVAL;
}
}
- return err;
+
+ return 0;
}
static int atmel_tdes_crypt(struct skcipher_request *req, unsigned long mode)
@@ -979,10 +967,8 @@ static int atmel_tdes_probe(struct platform_device *pdev)
err = devm_request_irq(&pdev->dev, tdes_dd->irq, atmel_tdes_irq,
IRQF_SHARED, "atmel-tdes", tdes_dd);
- if (err) {
- dev_err(dev, "unable to request tdes irq.\n");
+ if (err)
goto err_tasklet_kill;
- }
/* Initializing the clock */
tdes_dd->iclk = devm_clk_get(&pdev->dev, "tdes_clk");
diff --git a/drivers/crypto/bcm/cipher.c b/drivers/crypto/bcm/cipher.c
index 240b40ae9cd6..e9d9ca7441b6 100644
--- a/drivers/crypto/bcm/cipher.c
+++ b/drivers/crypto/bcm/cipher.c
@@ -2387,9 +2387,7 @@ static int ahash_hmac_setkey(struct crypto_ahash *ahash, const u8 *key,
* outer hashing in software.
*/
if (iproc_priv.spu.spu_type == SPU_TYPE_SPUM) {
- memcpy(ctx->ipad, ctx->authkey, ctx->authkeylen);
- memset(ctx->ipad + ctx->authkeylen, 0,
- blocksize - ctx->authkeylen);
+ memcpy_and_pad(ctx->ipad, blocksize, ctx->authkey, ctx->authkeylen, 0);
ctx->authkeylen = 0;
unsafe_memcpy(ctx->opad, ctx->ipad, blocksize,
"fortified memcpy causes -Wrestrict warning");
diff --git a/drivers/crypto/caam/Kconfig b/drivers/crypto/caam/Kconfig
index 05210a0edb8a..ec57bf6aaf6c 100644
--- a/drivers/crypto/caam/Kconfig
+++ b/drivers/crypto/caam/Kconfig
@@ -145,20 +145,11 @@ config CRYPTO_DEV_FSL_CAAM_PKC_API
config CRYPTO_DEV_FSL_CAAM_RNG_API
bool "Register caam device for hwrng API"
default y
- select CRYPTO_RNG
select HW_RANDOM
help
Selecting this will register the SEC4 hardware rng to
the hw_random API for supplying the kernel entropy pool.
-config CRYPTO_DEV_FSL_CAAM_PRNG_API
- bool "Register Pseudo random number generation implementation with Crypto API"
- default y
- select CRYPTO_RNG
- help
- Selecting this will register the SEC hardware prng to
- the Crypto API.
-
config CRYPTO_DEV_FSL_CAAM_BLOB_GEN
bool
diff --git a/drivers/crypto/caam/Makefile b/drivers/crypto/caam/Makefile
index d2eaf5205b1c..a17e3cf14c61 100644
--- a/drivers/crypto/caam/Makefile
+++ b/drivers/crypto/caam/Makefile
@@ -20,7 +20,6 @@ caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API) += caamalg.o
caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI) += caamalg_qi.o
caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API) += caamhash.o
caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API) += caamrng.o
-caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_PRNG_API) += caamprng.o
caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_PKC_API) += caampkc.o pkc_desc.o
caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_BLOB_GEN) += blob_gen.o
diff --git a/drivers/crypto/caam/caamprng.c b/drivers/crypto/caam/caamprng.c
deleted file mode 100644
index 6e4c1191cb28..000000000000
--- a/drivers/crypto/caam/caamprng.c
+++ /dev/null
@@ -1,241 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Driver to expose SEC4 PRNG via crypto RNG API
- *
- * Copyright 2022 NXP
- *
- */
-
-#include <linux/completion.h>
-#include <crypto/internal/rng.h>
-#include <linux/dma-mapping.h>
-#include <linux/kernel.h>
-#include "compat.h"
-#include "regs.h"
-#include "intern.h"
-#include "desc_constr.h"
-#include "jr.h"
-#include "error.h"
-
-/*
- * Length of used descriptors, see caam_init_desc()
- */
-#define CAAM_PRNG_MAX_DESC_LEN (CAAM_CMD_SZ + \
- CAAM_CMD_SZ + \
- CAAM_CMD_SZ + CAAM_PTR_SZ_MAX)
-
-/* prng per-device context */
-struct caam_prng_ctx {
- int err;
- struct completion done;
-};
-
-struct caam_prng_alg {
- struct rng_alg rng;
- bool registered;
-};
-
-static void caam_prng_done(struct device *jrdev, u32 *desc, u32 err,
- void *context)
-{
- struct caam_prng_ctx *jctx = context;
-
- jctx->err = err ? caam_jr_strstatus(jrdev, err) : 0;
-
- complete(&jctx->done);
-}
-
-static u32 *caam_init_reseed_desc(u32 *desc)
-{
- init_job_desc(desc, 0); /* + 1 cmd_sz */
- /* Generate random bytes: + 1 cmd_sz */
- append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG |
- OP_ALG_AS_FINALIZE);
-
- print_hex_dump_debug("prng reseed desc@: ", DUMP_PREFIX_ADDRESS,
- 16, 4, desc, desc_bytes(desc), 1);
-
- return desc;
-}
-
-static u32 *caam_init_prng_desc(u32 *desc, dma_addr_t dst_dma, u32 len)
-{
- init_job_desc(desc, 0); /* + 1 cmd_sz */
- /* Generate random bytes: + 1 cmd_sz */
- append_operation(desc, OP_ALG_ALGSEL_RNG | OP_TYPE_CLASS1_ALG);
- /* Store bytes: + 1 cmd_sz + caam_ptr_sz */
- append_fifo_store(desc, dst_dma,
- len, FIFOST_TYPE_RNGSTORE);
-
- print_hex_dump_debug("prng job desc@: ", DUMP_PREFIX_ADDRESS,
- 16, 4, desc, desc_bytes(desc), 1);
-
- return desc;
-}
-
-static int caam_prng_generate(struct crypto_rng *tfm,
- const u8 *src, unsigned int slen,
- u8 *dst, unsigned int dlen)
-{
- unsigned int aligned_dlen = ALIGN(dlen, dma_get_cache_alignment());
- struct caam_prng_ctx ctx;
- struct device *jrdev;
- dma_addr_t dst_dma;
- u32 *desc;
- u8 *buf;
- int ret;
-
- if (aligned_dlen < dlen)
- return -EOVERFLOW;
-
- buf = kzalloc(aligned_dlen, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
-
- jrdev = caam_jr_alloc();
- ret = PTR_ERR_OR_ZERO(jrdev);
- if (ret) {
- pr_err("Job Ring Device allocation failed\n");
- kfree(buf);
- return ret;
- }
-
- desc = kzalloc(CAAM_PRNG_MAX_DESC_LEN, GFP_KERNEL);
- if (!desc) {
- ret = -ENOMEM;
- goto out1;
- }
-
- dst_dma = dma_map_single(jrdev, buf, dlen, DMA_FROM_DEVICE);
- if (dma_mapping_error(jrdev, dst_dma)) {
- dev_err(jrdev, "Failed to map destination buffer memory\n");
- ret = -ENOMEM;
- goto out;
- }
-
- init_completion(&ctx.done);
- ret = caam_jr_enqueue(jrdev,
- caam_init_prng_desc(desc, dst_dma, dlen),
- caam_prng_done, &ctx);
-
- if (ret == -EINPROGRESS) {
- wait_for_completion(&ctx.done);
- ret = ctx.err;
- }
-
- dma_unmap_single(jrdev, dst_dma, dlen, DMA_FROM_DEVICE);
-
- if (!ret)
- memcpy(dst, buf, dlen);
-out:
- kfree(desc);
-out1:
- caam_jr_free(jrdev);
- kfree(buf);
- return ret;
-}
-
-static void caam_prng_exit(struct crypto_tfm *tfm) {}
-
-static int caam_prng_init(struct crypto_tfm *tfm)
-{
- return 0;
-}
-
-static int caam_prng_seed(struct crypto_rng *tfm,
- const u8 *seed, unsigned int slen)
-{
- struct caam_prng_ctx ctx;
- struct device *jrdev;
- u32 *desc;
- int ret;
-
- if (slen) {
- pr_err("Seed length should be zero\n");
- return -EINVAL;
- }
-
- jrdev = caam_jr_alloc();
- ret = PTR_ERR_OR_ZERO(jrdev);
- if (ret) {
- pr_err("Job Ring Device allocation failed\n");
- return ret;
- }
-
- desc = kzalloc(CAAM_PRNG_MAX_DESC_LEN, GFP_KERNEL);
- if (!desc) {
- caam_jr_free(jrdev);
- return -ENOMEM;
- }
-
- init_completion(&ctx.done);
- ret = caam_jr_enqueue(jrdev,
- caam_init_reseed_desc(desc),
- caam_prng_done, &ctx);
-
- if (ret == -EINPROGRESS) {
- wait_for_completion(&ctx.done);
- ret = ctx.err;
- }
-
- kfree(desc);
- caam_jr_free(jrdev);
- return ret;
-}
-
-static struct caam_prng_alg caam_prng_alg = {
- .rng = {
- .generate = caam_prng_generate,
- .seed = caam_prng_seed,
- .seedsize = 0,
- .base = {
- .cra_name = "stdrng",
- .cra_driver_name = "prng-caam",
- .cra_priority = 500,
- .cra_ctxsize = sizeof(struct caam_prng_ctx),
- .cra_module = THIS_MODULE,
- .cra_init = caam_prng_init,
- .cra_exit = caam_prng_exit,
- },
- }
-};
-
-void caam_prng_unregister(void *data)
-{
- if (caam_prng_alg.registered)
- crypto_unregister_rng(&caam_prng_alg.rng);
-}
-
-int caam_prng_register(struct device *ctrldev)
-{
- struct caam_drv_private *priv = dev_get_drvdata(ctrldev);
- u32 rng_inst;
- int ret = 0;
-
- /* Check for available RNG blocks before registration */
- if (priv->era < 10)
- rng_inst = (rd_reg32(&priv->jr[0]->perfmon.cha_num_ls) &
- CHA_ID_LS_RNG_MASK) >> CHA_ID_LS_RNG_SHIFT;
- else
- rng_inst = rd_reg32(&priv->jr[0]->vreg.rng) & CHA_VER_NUM_MASK;
-
- if (!rng_inst) {
- dev_dbg(ctrldev, "RNG block is not available... skipping registering algorithm\n");
- return ret;
- }
-
- ret = crypto_register_rng(&caam_prng_alg.rng);
- if (ret) {
- dev_err(ctrldev,
- "couldn't register rng crypto alg: %d\n",
- ret);
- return ret;
- }
-
- caam_prng_alg.registered = true;
-
- dev_info(ctrldev,
- "rng crypto API alg registered %s\n", caam_prng_alg.rng.base.cra_driver_name);
-
- return 0;
-}
diff --git a/drivers/crypto/caam/intern.h b/drivers/crypto/caam/intern.h
index a88da0d31b23..6e48bf7d6054 100644
--- a/drivers/crypto/caam/intern.h
+++ b/drivers/crypto/caam/intern.h
@@ -212,21 +212,6 @@ static inline void caam_rng_exit(struct device *dev) {}
#endif /* CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API */
-#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_PRNG_API
-
-int caam_prng_register(struct device *dev);
-void caam_prng_unregister(void *data);
-
-#else
-
-static inline int caam_prng_register(struct device *dev)
-{
- return 0;
-}
-
-static inline void caam_prng_unregister(void *data) {}
-#endif /* CONFIG_CRYPTO_DEV_FSL_CAAM_PRNG_API */
-
#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI
int caam_qi_algapi_init(struct device *dev);
diff --git a/drivers/crypto/caam/jr.c b/drivers/crypto/caam/jr.c
index 0ef00df9730e..239469f6882e 100644
--- a/drivers/crypto/caam/jr.c
+++ b/drivers/crypto/caam/jr.c
@@ -40,7 +40,6 @@ static void register_algs(struct caam_drv_private_jr *jrpriv,
caam_algapi_hash_init(dev);
caam_pkc_init(dev);
jrpriv->hwrng = !caam_rng_init(dev);
- caam_prng_register(dev);
caam_qi_algapi_init(dev);
algs_unlock:
@@ -55,7 +54,6 @@ static void unregister_algs(void)
goto algs_unlock;
caam_qi_algapi_exit();
- caam_prng_unregister(NULL);
caam_pkc_exit();
caam_algapi_hash_exit();
caam_algapi_exit();
@@ -576,23 +574,25 @@ static int caam_jr_init(struct device *dev)
return error;
}
-static void caam_jr_irq_dispose_mapping(void *data)
-{
- irq_dispose_mapping((unsigned long)data);
-}
-
/*
* Probe routine for each detected JobR subsystem.
*/
static int caam_jr_probe(struct platform_device *pdev)
{
struct device *jrdev;
- struct device_node *nprop;
- struct caam_job_ring __iomem *ctrl;
struct caam_drv_private_jr *jrpriv;
static int total_jobrs;
- struct resource *r;
+ void __iomem *ctrl;
int error;
+ int irq;
+
+ ctrl = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(ctrl))
+ return PTR_ERR(ctrl);
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0)
+ return irq;
jrdev = &pdev->dev;
jrpriv = devm_kzalloc(jrdev, sizeof(*jrpriv), GFP_KERNEL);
@@ -604,22 +604,7 @@ static int caam_jr_probe(struct platform_device *pdev)
/* save ring identity relative to detection */
jrpriv->ridx = total_jobrs++;
- nprop = pdev->dev.of_node;
- /* Get configuration properties from device tree */
- /* First, get register page */
- r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!r) {
- dev_err(jrdev, "platform_get_resource() failed\n");
- return -ENOMEM;
- }
-
- ctrl = devm_ioremap(jrdev, r->start, resource_size(r));
- if (!ctrl) {
- dev_err(jrdev, "devm_ioremap() failed\n");
- return -ENOMEM;
- }
-
- jrpriv->rregs = (struct caam_job_ring __iomem __force *)ctrl;
+ jrpriv->rregs = ctrl;
error = dma_set_mask_and_coherent(jrdev, caam_get_dma_mask(jrdev));
if (error) {
@@ -649,16 +634,7 @@ static int caam_jr_probe(struct platform_device *pdev)
}
/* Identify the interrupt */
- jrpriv->irq = irq_of_parse_and_map(nprop, 0);
- if (!jrpriv->irq) {
- dev_err(jrdev, "irq_of_parse_and_map failed\n");
- return -EINVAL;
- }
-
- error = devm_add_action_or_reset(jrdev, caam_jr_irq_dispose_mapping,
- (void *)(unsigned long)jrpriv->irq);
- if (error)
- return error;
+ jrpriv->irq = irq;
/* Now do the platform independent part */
error = caam_jr_init(jrdev); /* now turn on hardware */
diff --git a/drivers/crypto/cavium/nitrox/nitrox_hal.c b/drivers/crypto/cavium/nitrox/nitrox_hal.c
index 1b5abdb6cc5e..e36c1741bb78 100644
--- a/drivers/crypto/cavium/nitrox/nitrox_hal.c
+++ b/drivers/crypto/cavium/nitrox/nitrox_hal.c
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/delay.h>
+#include <linux/string.h>
#include "nitrox_dev.h"
#include "nitrox_csr.h"
@@ -647,7 +648,7 @@ void nitrox_get_hwinfo(struct nitrox_device *ndev)
ndev->hw.revision_id);
/* copy partname */
- strscpy(ndev->hw.partname, name, sizeof(ndev->hw.partname));
+ strscpy(ndev->hw.partname, name);
}
void enable_pf2vf_mbox_interrupts(struct nitrox_device *ndev)
diff --git a/drivers/crypto/ccp/ccp-crypto-sha.c b/drivers/crypto/ccp/ccp-crypto-sha.c
index 85058a89f35b..ff9bb253dbb2 100644
--- a/drivers/crypto/ccp/ccp-crypto-sha.c
+++ b/drivers/crypto/ccp/ccp-crypto-sha.c
@@ -426,7 +426,7 @@ static int ccp_register_hmac_alg(struct list_head *head,
*ccp_alg = *base_alg;
INIT_LIST_HEAD(&ccp_alg->entry);
- strscpy(ccp_alg->child_alg, def->name, CRYPTO_MAX_ALG_NAME);
+ strscpy(ccp_alg->child_alg, def->name);
alg = &ccp_alg->alg;
alg->setkey = ccp_sha_setkey;
diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c
index 0f72352030ba..f833cb7e4da3 100644
--- a/drivers/crypto/ccp/sev-dev.c
+++ b/drivers/crypto/ccp/sev-dev.c
@@ -245,6 +245,7 @@ static int sev_cmd_buffer_len(int cmd)
case SEV_CMD_SNP_LAUNCH_FINISH: return sizeof(struct sev_data_snp_launch_finish);
case SEV_CMD_SNP_DBG_DECRYPT: return sizeof(struct sev_data_snp_dbg);
case SEV_CMD_SNP_DBG_ENCRYPT: return sizeof(struct sev_data_snp_dbg);
+ case SEV_CMD_SNP_VERIFY_MITIGATION: return sizeof(struct sev_data_snp_verify_mitigation);
case SEV_CMD_SNP_PAGE_UNSMASH: return sizeof(struct sev_data_snp_page_unsmash);
case SEV_CMD_SNP_PLATFORM_STATUS: return sizeof(struct sev_data_snp_addr);
case SEV_CMD_SNP_GUEST_REQUEST: return sizeof(struct sev_data_snp_guest_request);
@@ -1348,6 +1349,162 @@ static int snp_filter_reserved_mem_regions(struct resource *rs, void *arg)
return 0;
}
+#ifdef CONFIG_SYSFS
+static int snp_verify_mitigation(u16 command, u64 vector,
+ struct sev_data_snp_verify_mitigation_dst *dst)
+{
+ struct sev_data_snp_verify_mitigation_dst *mit_dst = NULL;
+ struct sev_data_snp_verify_mitigation data = {0};
+ struct sev_device *sev = psp_master->sev_data;
+ int ret, error = 0;
+
+ mit_dst = snp_alloc_firmware_page(GFP_KERNEL | __GFP_ZERO);
+ if (!mit_dst)
+ return -ENOMEM;
+
+ data.length = sizeof(data);
+ data.subcommand = command;
+ data.vector = vector;
+ data.dst_paddr = __psp_pa(mit_dst);
+ data.dst_paddr_en = true;
+
+ ret = sev_do_cmd(SEV_CMD_SNP_VERIFY_MITIGATION, &data, &error);
+ if (!ret)
+ memcpy(dst, mit_dst, sizeof(*mit_dst));
+ else
+ dev_err(sev->dev, "SNP_VERIFY_MITIGATION command failed, ret = %d, error = %#x\n",
+ ret, error);
+
+ snp_free_firmware_page(mit_dst);
+
+ return ret;
+}
+
+static ssize_t supported_mitigations_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ struct sev_data_snp_verify_mitigation_dst dst;
+ int ret;
+
+ ret = snp_verify_mitigation(SNP_MIT_SUBCMD_REQ_STATUS, 0, &dst);
+ if (ret)
+ return ret;
+
+ return sysfs_emit(buf, "0x%llx\n", dst.mit_supported_vector);
+}
+
+static struct kobj_attribute supported_attr =
+ __ATTR_RO_MODE(supported_mitigations, 0400);
+
+static ssize_t verified_mitigations_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ struct sev_data_snp_verify_mitigation_dst dst;
+ int ret;
+
+ ret = snp_verify_mitigation(SNP_MIT_SUBCMD_REQ_STATUS, 0, &dst);
+ if (ret)
+ return ret;
+
+ return sysfs_emit(buf, "0x%llx\n", dst.mit_verified_vector);
+}
+
+static ssize_t verified_mitigations_store(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct sev_data_snp_verify_mitigation_dst dst;
+ struct sev_device *sev = psp_master->sev_data;
+ u64 vector;
+ int ret;
+
+ ret = kstrtoull(buf, 0, &vector);
+ if (ret)
+ return ret;
+
+ /*
+ * The firmware verifies a single mitigation per call. Reject vectors
+ * with more than one bit set early to avoid a guaranteed-to-fail call
+ */
+ if (hweight64(vector) != 1)
+ return -EINVAL;
+
+ ret = snp_verify_mitigation(SNP_MIT_SUBCMD_REQ_VERIFY, vector, &dst);
+ if (ret)
+ return ret;
+
+ if (dst.mit_failure_status) {
+ dev_err(sev->dev, "Verify Mitigation - failure status: 0x%x\n",
+ dst.mit_failure_status);
+ return -EINVAL;
+ }
+
+ return count;
+}
+
+static struct kobj_attribute verified_attr =
+ __ATTR_RW_MODE(verified_mitigations, 0600);
+
+static struct attribute *mitigation_attrs[] = {
+ &supported_attr.attr,
+ &verified_attr.attr,
+ NULL
+};
+
+static const struct attribute_group mit_attr_group = {
+ .attrs = mitigation_attrs,
+};
+
+static void sev_snp_register_verify_mitigation(struct sev_device *sev)
+{
+ int rc;
+
+ if (!(sev->snp_feat_info_0.ecx & SNP_VERIFY_MITIGATION_SUPPORTED) ||
+ sev->verify_mit)
+ return;
+
+ if (!sev->sev_kobj) {
+ sev->sev_kobj = kobject_create_and_add("sev", firmware_kobj);
+ if (!sev->sev_kobj)
+ return;
+ }
+
+ sev->verify_mit = kobject_create_and_add("vulnerabilities", sev->sev_kobj);
+ if (!sev->verify_mit)
+ goto err_sev_kobj;
+
+ rc = sysfs_create_group(sev->verify_mit, &mit_attr_group);
+ if (rc)
+ goto err_verify_mit;
+
+ return;
+
+err_verify_mit:
+ kobject_put(sev->verify_mit);
+ sev->verify_mit = NULL;
+err_sev_kobj:
+ kobject_put(sev->sev_kobj);
+ sev->sev_kobj = NULL;
+}
+
+static void sev_snp_unregister_verify_mitigation(struct sev_device *sev)
+{
+ if (sev->verify_mit) {
+ sysfs_remove_group(sev->verify_mit, &mit_attr_group);
+ kobject_put(sev->verify_mit);
+ sev->verify_mit = NULL;
+ }
+
+ if (sev->sev_kobj) {
+ kobject_put(sev->sev_kobj);
+ sev->sev_kobj = NULL;
+ }
+}
+#else // CONFIG_SYSFS
+static void sev_snp_register_verify_mitigation(struct sev_device *sev) { }
+static void sev_snp_unregister_verify_mitigation(struct sev_device *sev) { }
+#endif // CONFIG_SYSFS
+
static int __sev_snp_init_locked(int *error, unsigned int max_snp_asid)
{
struct sev_data_range_list *snp_range_list __free(kfree) = NULL;
@@ -1541,7 +1698,7 @@ static int __sev_platform_init_handle_init_ex_path(struct sev_device *sev)
if (sev_init_ex_buffer)
return 0;
- page = alloc_pages(GFP_KERNEL, get_order(NV_LENGTH));
+ page = alloc_pages(GFP_KERNEL | __GFP_ZERO, get_order(NV_LENGTH));
if (!page) {
dev_err(sev->dev, "SEV: INIT_EX NV memory allocation failed\n");
return -ENOMEM;
@@ -1551,20 +1708,31 @@ static int __sev_platform_init_handle_init_ex_path(struct sev_device *sev)
rc = sev_read_init_ex_file();
if (rc)
- return rc;
+ goto err_free;
/* If SEV-SNP is initialized, transition to firmware page. */
if (sev->snp_initialized) {
unsigned long npages;
npages = 1UL << get_order(NV_LENGTH);
- if (rmp_mark_pages_firmware(__pa(sev_init_ex_buffer), npages, false)) {
+ if (rmp_mark_pages_firmware(__pa(sev_init_ex_buffer), npages, true)) {
dev_err(sev->dev, "SEV: INIT_EX NV memory page state change failed.\n");
- return -ENOMEM;
+ rc = -ENOMEM;
+ /*
+ * Pages can be in an inconsistent state, don't release them back to the
+ * system.
+ */
+ goto err_reset;
}
}
return 0;
+
+err_free:
+ __free_pages(page, get_order(NV_LENGTH));
+err_reset:
+ sev_init_ex_buffer = NULL;
+ return rc;
}
static int __sev_platform_init_locked(int *error)
@@ -1671,6 +1839,17 @@ int sev_platform_init(struct sev_platform_init_args *args)
rc = _sev_platform_init_locked(args);
mutex_unlock(&sev_cmd_mutex);
+ /*
+ * Register the sysfs interface outside the sev_cmd_mutex. The
+ * _show()/_store() handlers issue SEV commands that acquire the
+ * sev_cmd_mutex, so creating (and on the shutdown path, removing) the
+ * sysfs group must stay outside that lock. sysfs provides its own
+ * synchronization between group creation/removal and concurrent
+ * attribute access.
+ */
+ if (!rc)
+ sev_snp_register_verify_mitigation(psp_master->sev_data);
+
return rc;
}
EXPORT_SYMBOL_GPL(sev_platform_init);
@@ -2765,6 +2944,15 @@ static void sev_firmware_shutdown(struct sev_device *sev)
if (sev->tio_status)
sev_tsm_uninit(sev);
+ /*
+ * Remove the sysfs interface before taking the sev_cmd_mutex.
+ * sysfs_remove_group() waits for in-flight _show()/_store() handlers
+ * to drain, and those handlers issue SNP_VERIFY_MITIGATION via
+ * sev_do_cmd() which acquires the sev_cmd_mutex. Removing the group
+ * while holding the mutex could therefore deadlock.
+ */
+ sev_snp_unregister_verify_mitigation(sev);
+
mutex_lock(&sev_cmd_mutex);
__sev_firmware_shutdown(sev, false);
diff --git a/drivers/crypto/ccp/sev-dev.h b/drivers/crypto/ccp/sev-dev.h
index b1cd556bbbf6..d5e596606def 100644
--- a/drivers/crypto/ccp/sev-dev.h
+++ b/drivers/crypto/ccp/sev-dev.h
@@ -59,6 +59,9 @@ struct sev_device {
bool snp_initialized;
+ struct kobject *sev_kobj;
+ struct kobject *verify_mit;
+
struct sev_user_data_status sev_plat_status;
struct sev_user_data_snp_status snp_plat_status;
diff --git a/drivers/crypto/ccree/cc_driver.c b/drivers/crypto/ccree/cc_driver.c
index 061e68a31c36..28a23cd572d6 100644
--- a/drivers/crypto/ccree/cc_driver.c
+++ b/drivers/crypto/ccree/cc_driver.c
@@ -471,10 +471,8 @@ static int init_cc_resources(struct platform_device *plat_dev)
/* register the driver isr function */
rc = devm_request_irq(dev, irq, cc_isr, IRQF_SHARED, "ccree",
new_drvdata);
- if (rc) {
- dev_err(dev, "Could not register to interrupt %d\n", irq);
+ if (rc)
goto post_pm_err;
- }
dev_dbg(dev, "Registered to IRQ: %d\n", irq);
init_cc_cache_params(new_drvdata);
diff --git a/drivers/crypto/gemini/sl3516-ce-cipher.c b/drivers/crypto/gemini/sl3516-ce-cipher.c
index 583010b2d007..02ec4282333b 100644
--- a/drivers/crypto/gemini/sl3516-ce-cipher.c
+++ b/drivers/crypto/gemini/sl3516-ce-cipher.c
@@ -56,10 +56,6 @@ static bool sl3516_ce_need_fallback(struct skcipher_request *areq)
ce->fallback_mod16++;
return true;
}
- if ((sg_dma_len(sg) % 16) != 0) {
- ce->fallback_mod16++;
- return true;
- }
if (!IS_ALIGNED(sg->offset, 16)) {
ce->fallback_align16++;
return true;
@@ -72,10 +68,6 @@ static bool sl3516_ce_need_fallback(struct skcipher_request *areq)
ce->fallback_mod16++;
return true;
}
- if ((sg_dma_len(sg) % 16) != 0) {
- ce->fallback_mod16++;
- return true;
- }
if (!IS_ALIGNED(sg->offset, 16)) {
ce->fallback_align16++;
return true;
diff --git a/drivers/crypto/gemini/sl3516-ce-core.c b/drivers/crypto/gemini/sl3516-ce-core.c
index f7e0e3fea15c..c1df5f96ea42 100644
--- a/drivers/crypto/gemini/sl3516-ce-core.c
+++ b/drivers/crypto/gemini/sl3516-ce-core.c
@@ -414,10 +414,8 @@ static int sl3516_ce_probe(struct platform_device *pdev)
return irq;
err = devm_request_irq(&pdev->dev, irq, ce_irq_handler, 0, "crypto", ce);
- if (err) {
- dev_err(ce->dev, "Cannot request Crypto Engine IRQ (err=%d)\n", err);
+ if (err)
return err;
- }
ce->reset = devm_reset_control_get(&pdev->dev, NULL);
if (IS_ERR(ce->reset))
diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c
index a951d2ef7833..c01966a4a33f 100644
--- a/drivers/crypto/hisilicon/qm.c
+++ b/drivers/crypto/hisilicon/qm.c
@@ -2944,11 +2944,8 @@ static int qm_alloc_uacce(struct hisi_qm *qm)
.flags = UACCE_DEV_SVA,
.ops = &uacce_qm_ops,
};
- int ret;
- ret = strscpy(interface.name, dev_driver_string(&pdev->dev),
- sizeof(interface.name));
- if (ret < 0)
+ if (strscpy(interface.name, dev_driver_string(&pdev->dev)) < 0)
return -ENAMETOOLONG;
uacce = uacce_alloc(&pdev->dev, &interface);
diff --git a/drivers/crypto/hisilicon/sec/sec_drv.c b/drivers/crypto/hisilicon/sec/sec_drv.c
index 129cb6faa0b7..2514a5e1f9b4 100644
--- a/drivers/crypto/hisilicon/sec/sec_drv.c
+++ b/drivers/crypto/hisilicon/sec/sec_drv.c
@@ -1010,25 +1010,12 @@ static void sec_queue_base_init(struct sec_dev_info *info,
static int sec_map_io(struct sec_dev_info *info, struct platform_device *pdev)
{
- struct resource *res;
int i;
for (i = 0; i < SEC_NUM_ADDR_REGIONS; i++) {
- res = platform_get_resource(pdev, IORESOURCE_MEM, i);
-
- if (!res) {
- dev_err(info->dev, "Memory resource %d not found\n", i);
- return -EINVAL;
- }
-
- info->regs[i] = devm_ioremap(info->dev, res->start,
- resource_size(res));
- if (!info->regs[i]) {
- dev_err(info->dev,
- "Memory resource %d could not be remapped\n",
- i);
- return -EINVAL;
- }
+ info->regs[i] = devm_platform_ioremap_resource(pdev, i);
+ if (IS_ERR(info->regs[i]))
+ return PTR_ERR(info->regs[i]);
}
return 0;
diff --git a/drivers/crypto/hisilicon/sec2/sec.h b/drivers/crypto/hisilicon/sec2/sec.h
index adf95795dffe..c12a39a8a9d4 100644
--- a/drivers/crypto/hisilicon/sec2/sec.h
+++ b/drivers/crypto/hisilicon/sec2/sec.h
@@ -181,9 +181,6 @@ struct sec_ctx {
const struct sec_req_op *req_op;
struct hisi_qp **qps;
- /* Half queues for encipher, and half for decipher */
- u32 hlf_q_num;
-
/* Current cyclic index to select a queue for encipher */
atomic_t enc_qcyclic;
diff --git a/drivers/crypto/hisilicon/sec2/sec_crypto.c b/drivers/crypto/hisilicon/sec2/sec_crypto.c
index 77e0e03cbcab..0a2f7c8b44fc 100644
--- a/drivers/crypto/hisilicon/sec2/sec_crypto.c
+++ b/drivers/crypto/hisilicon/sec2/sec_crypto.c
@@ -96,7 +96,6 @@
#define IV_FLAGS_OFFSET 0x6
#define IV_CM_OFFSET 0x3
#define IV_LAST_BYTE1 1
-#define IV_LAST_BYTE2 2
#define IV_LAST_BYTE_MASK 0xFF
#define IV_CTR_INIT 0x1
#define IV_BYTE_OFFSET 0x8
@@ -669,9 +668,13 @@ static int sec_ctx_base_init(struct sec_ctx *ctx)
sec = container_of(ctx->qps[0]->qm, struct sec_dev, qm);
ctx->sec = sec;
ctx->dev = &sec->qm.pdev->dev;
- ctx->hlf_q_num = sec->ctx_q_num >> 1;
ctx->pbuf_supported = ctx->sec->iommu_used;
+ if (sec->qm.ver < QM_HW_V3)
+ ctx->type_supported = SEC_BD_TYPE2;
+ else
+ ctx->type_supported = SEC_BD_TYPE3;
+
ctx->qp_ctx = kzalloc_objs(struct sec_qp_ctx, sec->ctx_q_num);
if (!ctx->qp_ctx) {
ret = -ENOMEM;
@@ -1696,7 +1699,7 @@ static void set_aead_auth_iv(struct sec_ctx *ctx, struct sec_req *req)
struct sec_cipher_req *c_req = &req->c_req;
u32 data_size = aead_req->cryptlen;
u8 flage = 0;
- u8 cm, cl;
+ u8 cm, cl, i;
/* the specification has been checked in aead_iv_demension_check() */
cl = c_req->c_ivin[0] + 1;
@@ -1720,15 +1723,16 @@ static void set_aead_auth_iv(struct sec_ctx *ctx, struct sec_req *req)
* the last 32bit is counter's initial number,
* but the nonce uses the first 16bit
* the tail 16bit fill with the cipher length
+ * When CL is 3, the tail 24bit fill with the cipher length.
*/
if (!c_req->encrypt)
data_size = aead_req->cryptlen - authsize;
- a_req->a_ivin[ctx->c_ctx.ivsize - IV_LAST_BYTE1] =
- data_size & IV_LAST_BYTE_MASK;
- data_size >>= IV_BYTE_OFFSET;
- a_req->a_ivin[ctx->c_ctx.ivsize - IV_LAST_BYTE2] =
+ for (i = 1; i <= cl; i++) {
+ a_req->a_ivin[ctx->c_ctx.ivsize - i] =
data_size & IV_LAST_BYTE_MASK;
+ data_size >>= IV_BYTE_OFFSET;
+ }
}
static void sec_aead_set_iv(struct sec_ctx *ctx, struct sec_req *req)
@@ -2067,13 +2071,10 @@ static int sec_skcipher_ctx_init(struct crypto_skcipher *tfm)
if (!ctx->qps)
return 0;
- if (ctx->sec->qm.ver < QM_HW_V3) {
- ctx->type_supported = SEC_BD_TYPE2;
- ctx->req_op = &sec_skcipher_req_ops;
- } else {
- ctx->type_supported = SEC_BD_TYPE3;
+ if (ctx->type_supported == SEC_BD_TYPE3)
ctx->req_op = &sec_skcipher_req_ops_v3;
- }
+ else
+ ctx->req_op = &sec_skcipher_req_ops;
return 0;
}
@@ -2100,13 +2101,11 @@ static int sec_aead_init(struct crypto_aead *tfm)
ret = sec_ctx_base_init(ctx);
if (ret)
return ret;
- if (ctx->sec->qm.ver < QM_HW_V3) {
- ctx->type_supported = SEC_BD_TYPE2;
- ctx->req_op = &sec_aead_req_ops;
- } else {
- ctx->type_supported = SEC_BD_TYPE3;
+
+ if (ctx->type_supported == SEC_BD_TYPE3)
ctx->req_op = &sec_aead_req_ops_v3;
- }
+ else
+ ctx->req_op = &sec_aead_req_ops;
ret = sec_auth_init(ctx);
if (ret)
diff --git a/drivers/crypto/img-hash.c b/drivers/crypto/img-hash.c
index 0f19dcc2f388..1ccfc0eccc73 100644
--- a/drivers/crypto/img-hash.c
+++ b/drivers/crypto/img-hash.c
@@ -966,10 +966,8 @@ static int img_hash_probe(struct platform_device *pdev)
err = devm_request_irq(dev, irq, img_irq_handler, 0,
dev_name(dev), hdev);
- if (err) {
- dev_err(dev, "unable to request irq\n");
+ if (err)
goto res_err;
- }
dev_dbg(dev, "using IRQ channel %d\n", irq);
hdev->hash_clk = devm_clk_get_enabled(&pdev->dev, "hash");
diff --git a/drivers/crypto/inside-secure/eip93/eip93-main.c b/drivers/crypto/inside-secure/eip93/eip93-main.c
index 1a8dabc4ada4..e62785952b0d 100644
--- a/drivers/crypto/inside-secure/eip93/eip93-main.c
+++ b/drivers/crypto/inside-secure/eip93/eip93-main.c
@@ -415,7 +415,7 @@ static int eip93_crypto_probe(struct platform_device *pdev)
u32 ver, algo_flags;
int ret;
- eip93 = devm_kzalloc(dev, sizeof(*eip93), GFP_KERNEL);
+ eip93 = devm_kzalloc(dev, struct_size(eip93, ring, 1), GFP_KERNEL);
if (!eip93)
return -ENOMEM;
@@ -436,10 +436,6 @@ static int eip93_crypto_probe(struct platform_device *pdev)
if (ret)
return ret;
- eip93->ring = devm_kcalloc(eip93->dev, 1, sizeof(*eip93->ring), GFP_KERNEL);
- if (!eip93->ring)
- return -ENOMEM;
-
ret = eip93_desc_init(eip93);
if (ret)
return ret;
diff --git a/drivers/crypto/inside-secure/eip93/eip93-main.h b/drivers/crypto/inside-secure/eip93/eip93-main.h
index 990c2401b7ce..5f0f51081743 100644
--- a/drivers/crypto/inside-secure/eip93/eip93-main.h
+++ b/drivers/crypto/inside-secure/eip93/eip93-main.h
@@ -92,17 +92,6 @@
EIP93_HASH_SHA224 | \
EIP93_HASH_SHA256))
-/**
- * struct eip93_device - crypto engine device structure
- */
-struct eip93_device {
- void __iomem *base;
- struct device *dev;
- struct clk *clk;
- int irq;
- struct eip93_ring *ring;
-};
-
struct eip93_desc_ring {
void *base;
void *base_end;
@@ -131,6 +120,17 @@ struct eip93_ring {
struct idr crypto_async_idr;
};
+/**
+ * struct eip93_device - crypto engine device structure
+ */
+struct eip93_device {
+ void __iomem *base;
+ struct device *dev;
+ struct clk *clk;
+ int irq;
+ struct eip93_ring ring[];
+};
+
enum eip93_alg_type {
EIP93_ALG_TYPE_AEAD,
EIP93_ALG_TYPE_SKCIPHER,
diff --git a/drivers/crypto/inside-secure/safexcel.c b/drivers/crypto/inside-secure/safexcel.c
index 52809e57361a..71b920e17e98 100644
--- a/drivers/crypto/inside-secure/safexcel.c
+++ b/drivers/crypto/inside-secure/safexcel.c
@@ -1172,10 +1172,8 @@ static int safexcel_request_ring_irq(void *pdev, int irqid,
ret = devm_request_threaded_irq(dev, irq, handler,
threaded_handler, IRQF_ONESHOT,
dev_name(dev), ring_irq_priv);
- if (ret) {
- dev_err(dev, "unable to request IRQ %d\n", irq);
+ if (ret)
return ret;
- }
/* Set affinity */
cpu = cpumask_local_spread(ring_id, NUMA_NO_NODE);
diff --git a/drivers/crypto/intel/iaa/iaa_crypto_main.c b/drivers/crypto/intel/iaa/iaa_crypto_main.c
index f62b994e18e5..c9ab4b83ae02 100644
--- a/drivers/crypto/intel/iaa/iaa_crypto_main.c
+++ b/drivers/crypto/intel/iaa/iaa_crypto_main.c
@@ -2,12 +2,14 @@
/* Copyright(c) 2021 Intel Corporation. All rights rsvd. */
#include <linux/init.h>
+#include <linux/crypto.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/sysfs.h>
#include <linux/device.h>
#include <linux/iommu.h>
+#include <linux/mempool.h>
#include <uapi/linux/idxd.h>
#include <linux/highmem.h>
#include <linux/sched/smt.h>
@@ -156,6 +158,16 @@ static bool async_mode;
/* Use interrupts */
static bool use_irq;
+struct iaa_req_ctx {
+ u32 compression_crc;
+ struct page *bounce_src;
+ dma_addr_t bounce_src_dma;
+ unsigned int bounce_src_len;
+};
+
+static mempool_t *iaa_bounce_pool;
+#define IAA_BOUNCE_POOL_SIZE 128
+
/**
* set_iaa_sync_mode - Set IAA sync mode
* @name: The name of the sync mode
@@ -983,6 +995,28 @@ out:
return ret;
}
+static bool iaa_error_should_retry(struct idxd_desc *idxd_desc)
+{
+ return idxd_desc->iax_completion->status == IAA_ANALYTICS_ERROR;
+}
+
+static void iaa_unmap_src(struct device *dev, struct acomp_req *req)
+{
+ struct iaa_req_ctx *req_ctx = acomp_request_ctx(req);
+
+ if (req_ctx->bounce_src) {
+ dma_unmap_page(dev, req_ctx->bounce_src_dma,
+ req_ctx->bounce_src_len, DMA_TO_DEVICE);
+ mempool_free(req_ctx->bounce_src, iaa_bounce_pool);
+ req_ctx->bounce_src = NULL;
+ req_ctx->bounce_src_dma = 0;
+ req_ctx->bounce_src_len = 0;
+ return;
+ }
+
+ dma_unmap_sg(dev, req->src, 1, DMA_TO_DEVICE);
+}
+
static int deflate_generic_decompress(struct acomp_req *req)
{
ACOMP_FBREQ_ON_STACK(fbreq, req);
@@ -996,6 +1030,19 @@ static int deflate_generic_decompress(struct acomp_req *req)
return ret;
}
+static int deflate_generic_compress(struct acomp_req *req)
+{
+ ACOMP_FBREQ_ON_STACK(fbreq, req);
+ int ret;
+
+ ret = crypto_acomp_compress(fbreq);
+ req->dlen = fbreq->dlen;
+
+ update_total_sw_comp_calls();
+
+ return ret;
+}
+
static int iaa_remap_for_verify(struct device *dev, struct iaa_wq *iaa_wq,
struct acomp_req *req,
dma_addr_t *src_addr, dma_addr_t *dst_addr);
@@ -1013,6 +1060,7 @@ static void iaa_desc_complete(struct idxd_desc *idxd_desc,
struct iaa_device_compression_mode *active_compression_mode;
struct iaa_compression_ctx *compression_ctx;
struct crypto_ctx *ctx = __ctx;
+ struct iaa_req_ctx *req_ctx = acomp_request_ctx(ctx->req);
struct iaa_device *iaa_device;
struct idxd_device *idxd;
struct iaa_wq *iaa_wq;
@@ -1039,40 +1087,44 @@ static void iaa_desc_complete(struct idxd_desc *idxd_desc,
ctx->compress, false);
if (ret) {
dev_dbg(dev, "%s: check_completion failed ret=%d\n", __func__, ret);
- if (!ctx->compress &&
- idxd_desc->iax_completion->status == IAA_ANALYTICS_ERROR) {
+ if (!ctx->compress && iaa_error_should_retry(idxd_desc)) {
pr_warn("%s: falling back to deflate-generic decompress, "
"analytics error code %x\n", __func__,
idxd_desc->iax_completion->error_code);
+ dma_unmap_sg(dev, ctx->req->dst, sg_nents(ctx->req->dst),
+ DMA_FROM_DEVICE);
+ iaa_unmap_src(dev, ctx->req);
+
ret = deflate_generic_decompress(ctx->req);
if (ret) {
dev_dbg(dev, "%s: deflate-generic failed ret=%d\n",
__func__, ret);
err = -EIO;
- goto err;
}
+ goto out;
} else {
err = -EIO;
goto err;
}
} else {
ctx->req->dlen = idxd_desc->iax_completion->output_size;
+
+ if (!ctx->compress) {
+ update_total_decomp_bytes_in(ctx->req->slen);
+ update_wq_decomp_bytes(iaa_wq->wq, ctx->req->slen);
+ }
}
/* Update stats */
if (ctx->compress) {
update_total_comp_bytes_out(ctx->req->dlen);
update_wq_comp_bytes(iaa_wq->wq, ctx->req->dlen);
- } else {
- update_total_decomp_bytes_in(ctx->req->slen);
- update_wq_decomp_bytes(iaa_wq->wq, ctx->req->slen);
}
if (ctx->compress && compression_ctx->verify_compress) {
- u32 *compression_crc = acomp_request_ctx(ctx->req);
dma_addr_t src_addr, dst_addr;
- *compression_crc = idxd_desc->iax_completion->crc;
+ req_ctx->compression_crc = idxd_desc->iax_completion->crc;
ret = iaa_remap_for_verify(dev, iaa_wq, ctx->req, &src_addr, &dst_addr);
if (ret) {
@@ -1095,7 +1147,7 @@ static void iaa_desc_complete(struct idxd_desc *idxd_desc,
}
err:
dma_unmap_sg(dev, ctx->req->dst, sg_nents(ctx->req->dst), DMA_FROM_DEVICE);
- dma_unmap_sg(dev, ctx->req->src, sg_nents(ctx->req->src), DMA_TO_DEVICE);
+ iaa_unmap_src(dev, ctx->req);
out:
if (ret != 0)
dev_dbg(dev, "asynchronous compress failed ret=%d\n", ret);
@@ -1115,7 +1167,7 @@ static int iaa_compress(struct crypto_tfm *tfm, struct acomp_req *req,
{
struct iaa_device_compression_mode *active_compression_mode;
struct iaa_compression_ctx *ctx = crypto_tfm_ctx(tfm);
- u32 *compression_crc = acomp_request_ctx(req);
+ struct iaa_req_ctx *req_ctx = acomp_request_ctx(req);
struct iaa_device *iaa_device;
struct idxd_desc *idxd_desc;
struct iax_hw_desc *desc;
@@ -1206,7 +1258,7 @@ static int iaa_compress(struct crypto_tfm *tfm, struct acomp_req *req,
update_total_comp_bytes_out(*dlen);
update_wq_comp_bytes(wq, *dlen);
- *compression_crc = idxd_desc->iax_completion->crc;
+ req_ctx->compression_crc = idxd_desc->iax_completion->crc;
if (!ctx->async_mode)
idxd_free_desc(wq, idxd_desc);
@@ -1266,7 +1318,7 @@ static int iaa_compress_verify(struct crypto_tfm *tfm, struct acomp_req *req,
{
struct iaa_device_compression_mode *active_compression_mode;
struct iaa_compression_ctx *ctx = crypto_tfm_ctx(tfm);
- u32 *compression_crc = acomp_request_ctx(req);
+ struct iaa_req_ctx *req_ctx = acomp_request_ctx(req);
struct iaa_device *iaa_device;
struct idxd_desc *idxd_desc;
struct iax_hw_desc *desc;
@@ -1326,10 +1378,10 @@ static int iaa_compress_verify(struct crypto_tfm *tfm, struct acomp_req *req,
goto err;
}
- if (*compression_crc != idxd_desc->iax_completion->crc) {
+ if (req_ctx->compression_crc != idxd_desc->iax_completion->crc) {
ret = -EINVAL;
- dev_dbg(dev, "(verify) iaa comp/decomp crc mismatch:"
- " comp=0x%x, decomp=0x%x\n", *compression_crc,
+ dev_dbg(dev, "(verify) iaa comp/decomp crc mismatch: comp=0x%x, decomp=0x%x\n",
+ req_ctx->compression_crc,
idxd_desc->iax_completion->crc);
print_hex_dump(KERN_INFO, "cmp-rec: ", DUMP_PREFIX_OFFSET,
8, 1, idxd_desc->iax_completion, 64, 0);
@@ -1433,31 +1485,21 @@ static int iaa_decompress(struct crypto_tfm *tfm, struct acomp_req *req,
ret = check_completion(dev, idxd_desc->iax_completion, false, false);
if (ret) {
dev_dbg(dev, "%s: check_completion failed ret=%d\n", __func__, ret);
- if (idxd_desc->iax_completion->status == IAA_ANALYTICS_ERROR) {
- pr_warn("%s: falling back to deflate-generic decompress, "
- "analytics error code %x\n", __func__,
- idxd_desc->iax_completion->error_code);
- ret = deflate_generic_decompress(req);
- if (ret) {
- dev_dbg(dev, "%s: deflate-generic failed ret=%d\n",
- __func__, ret);
- goto err;
- }
- } else {
- goto err;
- }
+ if (iaa_error_should_retry(idxd_desc))
+ ret = -EAGAIN;
+ goto err;
} else {
req->dlen = idxd_desc->iax_completion->output_size;
+
+ /* Update stats */
+ update_total_decomp_bytes_in(slen);
+ update_wq_decomp_bytes(wq, slen);
}
*dlen = req->dlen;
if (!ctx->async_mode)
idxd_free_desc(wq, idxd_desc);
-
- /* Update stats */
- update_total_decomp_bytes_in(slen);
- update_wq_decomp_bytes(wq, slen);
out:
return ret;
err:
@@ -1469,14 +1511,19 @@ err:
static int iaa_comp_acompress(struct acomp_req *req)
{
+ struct iaa_req_ctx *req_ctx = acomp_request_ctx(req);
struct iaa_compression_ctx *compression_ctx;
struct crypto_tfm *tfm = req->base.tfm;
dma_addr_t src_addr, dst_addr;
- int nr_sgs, cpu, ret = 0;
+ int cpu, ret = 0;
struct iaa_wq *iaa_wq;
struct idxd_wq *wq;
struct device *dev;
+ req_ctx->bounce_src = NULL;
+ req_ctx->bounce_src_dma = 0;
+ req_ctx->bounce_src_len = 0;
+
compression_ctx = crypto_tfm_ctx(tfm);
if (!iaa_crypto_enabled) {
@@ -1484,11 +1531,15 @@ static int iaa_comp_acompress(struct acomp_req *req)
return -ENODEV;
}
- if (!req->src || !req->slen) {
- pr_debug("invalid src, not compressing\n");
+ if (!req->src || !req->slen || !req->dst) {
+ pr_debug("invalid req, not compressing\n");
return -EINVAL;
}
+ /* Fall back to software if src or dst has multiple sg entries */
+ if (sg_nents(req->src) > 1 || sg_nents(req->dst) > 1)
+ return deflate_generic_compress(req);
+
cpu = get_cpu();
wq = wq_table_next_wq(cpu);
put_cpu();
@@ -1507,30 +1558,25 @@ static int iaa_comp_acompress(struct acomp_req *req)
dev = &wq->idxd->pdev->dev;
- nr_sgs = dma_map_sg(dev, req->src, sg_nents(req->src), DMA_TO_DEVICE);
- if (nr_sgs <= 0 || nr_sgs > 1) {
- dev_dbg(dev, "couldn't map src sg for iaa device %d,"
- " wq %d: ret=%d\n", iaa_wq->iaa_device->idxd->id,
- iaa_wq->wq->id, ret);
- ret = -EIO;
- goto out;
+ if (!dma_map_sg(dev, req->src, 1, DMA_TO_DEVICE)) {
+ dev_dbg(dev, "couldn't map src sg for iaa device %d, wq %d\n",
+ iaa_wq->iaa_device->idxd->id, iaa_wq->wq->id);
+ iaa_wq_put(wq);
+ return deflate_generic_compress(req);
}
src_addr = sg_dma_address(req->src);
- dev_dbg(dev, "dma_map_sg, src_addr %llx, nr_sgs %d, req->src %p,"
- " req->slen %d, sg_dma_len(sg) %d\n", src_addr, nr_sgs,
+ dev_dbg(dev, "map src %llx req->src %p slen %d sg_len %d\n", src_addr,
req->src, req->slen, sg_dma_len(req->src));
- nr_sgs = dma_map_sg(dev, req->dst, sg_nents(req->dst), DMA_FROM_DEVICE);
- if (nr_sgs <= 0 || nr_sgs > 1) {
- dev_dbg(dev, "couldn't map dst sg for iaa device %d,"
- " wq %d: ret=%d\n", iaa_wq->iaa_device->idxd->id,
- iaa_wq->wq->id, ret);
- ret = -EIO;
- goto err_map_dst;
+ if (!dma_map_sg(dev, req->dst, 1, DMA_FROM_DEVICE)) {
+ dev_dbg(dev, "couldn't map dst sg for iaa device %d, wq %d\n",
+ iaa_wq->iaa_device->idxd->id, iaa_wq->wq->id);
+ dma_unmap_sg(dev, req->src, 1, DMA_TO_DEVICE);
+ iaa_wq_put(wq);
+ return deflate_generic_compress(req);
}
dst_addr = sg_dma_address(req->dst);
- dev_dbg(dev, "dma_map_sg, dst_addr %llx, nr_sgs %d, req->dst %p,"
- " req->dlen %d, sg_dma_len(sg) %d\n", dst_addr, nr_sgs,
+ dev_dbg(dev, "map dst %llx req->dst %p dlen %d sg_len %d\n", dst_addr,
req->dst, req->dlen, sg_dma_len(req->dst));
ret = iaa_compress(tfm, req, wq, src_addr, req->slen, dst_addr,
@@ -1550,8 +1596,8 @@ static int iaa_comp_acompress(struct acomp_req *req)
if (ret)
dev_dbg(dev, "asynchronous compress verification failed ret=%d\n", ret);
- dma_unmap_sg(dev, req->dst, sg_nents(req->dst), DMA_TO_DEVICE);
- dma_unmap_sg(dev, req->src, sg_nents(req->src), DMA_FROM_DEVICE);
+ dma_unmap_sg(dev, req->dst, 1, DMA_TO_DEVICE);
+ dma_unmap_sg(dev, req->src, 1, DMA_FROM_DEVICE);
goto out;
}
@@ -1559,9 +1605,8 @@ static int iaa_comp_acompress(struct acomp_req *req)
if (ret)
dev_dbg(dev, "asynchronous compress failed ret=%d\n", ret);
- dma_unmap_sg(dev, req->dst, sg_nents(req->dst), DMA_FROM_DEVICE);
-err_map_dst:
- dma_unmap_sg(dev, req->src, sg_nents(req->src), DMA_TO_DEVICE);
+ dma_unmap_sg(dev, req->dst, 1, DMA_FROM_DEVICE);
+ dma_unmap_sg(dev, req->src, 1, DMA_TO_DEVICE);
out:
iaa_wq_put(wq);
@@ -1570,23 +1615,40 @@ out:
static int iaa_comp_adecompress(struct acomp_req *req)
{
+ struct iaa_req_ctx *req_ctx = acomp_request_ctx(req);
struct crypto_tfm *tfm = req->base.tfm;
dma_addr_t src_addr, dst_addr;
- int nr_sgs, cpu, ret = 0;
+ bool use_bounce_src = false;
+ int cpu, ret = 0;
struct iaa_wq *iaa_wq;
struct device *dev;
struct idxd_wq *wq;
+ struct page *page;
+
+ req_ctx->bounce_src = NULL;
+ req_ctx->bounce_src_dma = 0;
+ req_ctx->bounce_src_len = 0;
if (!iaa_crypto_enabled) {
pr_debug("iaa_crypto disabled, not decompressing\n");
return -ENODEV;
}
- if (!req->src || !req->slen) {
- pr_debug("invalid src, not decompressing\n");
+ if (!req->src || !req->slen || !req->dst) {
+ pr_debug("invalid req, not decompressing\n");
return -EINVAL;
}
+ /* Fall back to software if dst has multiple sg entries */
+ if (sg_nents(req->dst) > 1)
+ return deflate_generic_decompress(req);
+
+ if (sg_nents(req->src) > 1) {
+ if (req->slen > PAGE_SIZE)
+ return deflate_generic_decompress(req);
+ use_bounce_src = true;
+ }
+
cpu = get_cpu();
wq = wq_table_next_wq(cpu);
put_cpu();
@@ -1605,30 +1667,52 @@ static int iaa_comp_adecompress(struct acomp_req *req)
dev = &wq->idxd->pdev->dev;
- nr_sgs = dma_map_sg(dev, req->src, sg_nents(req->src), DMA_TO_DEVICE);
- if (nr_sgs <= 0 || nr_sgs > 1) {
- dev_dbg(dev, "couldn't map src sg for iaa device %d,"
- " wq %d: ret=%d\n", iaa_wq->iaa_device->idxd->id,
- iaa_wq->wq->id, ret);
- ret = -EIO;
- goto out;
+ if (unlikely(use_bounce_src)) {
+ page = mempool_alloc(iaa_bounce_pool, GFP_ATOMIC);
+ if (!page) {
+ iaa_wq_put(wq);
+ return deflate_generic_decompress(req);
+ }
+
+ if (sg_copy_to_buffer(req->src, sg_nents(req->src),
+ page_address(page), req->slen) != req->slen) {
+ mempool_free(page, iaa_bounce_pool);
+ iaa_wq_put(wq);
+ return deflate_generic_decompress(req);
+ }
+
+ src_addr = dma_map_page(dev, page, 0, req->slen, DMA_TO_DEVICE);
+ if (dma_mapping_error(dev, src_addr)) {
+ mempool_free(page, iaa_bounce_pool);
+ iaa_wq_put(wq);
+ return deflate_generic_decompress(req);
+ }
+
+ req_ctx->bounce_src = page;
+ req_ctx->bounce_src_dma = src_addr;
+ req_ctx->bounce_src_len = req->slen;
+ } else {
+ if (!dma_map_sg(dev, req->src, 1, DMA_TO_DEVICE)) {
+ dev_dbg(dev, "couldn't map src sg for iaa device %d, wq %d\n",
+ iaa_wq->iaa_device->idxd->id, iaa_wq->wq->id);
+ iaa_wq_put(wq);
+ return deflate_generic_decompress(req);
+ }
+
+ src_addr = sg_dma_address(req->src);
+ dev_dbg(dev, "map src %llx req->src %p slen %d sg_len %d\n", src_addr,
+ req->src, req->slen, sg_dma_len(req->src));
}
- src_addr = sg_dma_address(req->src);
- dev_dbg(dev, "dma_map_sg, src_addr %llx, nr_sgs %d, req->src %p,"
- " req->slen %d, sg_dma_len(sg) %d\n", src_addr, nr_sgs,
- req->src, req->slen, sg_dma_len(req->src));
- nr_sgs = dma_map_sg(dev, req->dst, sg_nents(req->dst), DMA_FROM_DEVICE);
- if (nr_sgs <= 0 || nr_sgs > 1) {
- dev_dbg(dev, "couldn't map dst sg for iaa device %d,"
- " wq %d: ret=%d\n", iaa_wq->iaa_device->idxd->id,
- iaa_wq->wq->id, ret);
- ret = -EIO;
- goto err_map_dst;
+ if (!dma_map_sg(dev, req->dst, 1, DMA_FROM_DEVICE)) {
+ dev_dbg(dev, "couldn't map dst sg for iaa device %d, wq %d\n",
+ iaa_wq->iaa_device->idxd->id, iaa_wq->wq->id);
+ iaa_unmap_src(dev, req);
+ iaa_wq_put(wq);
+ return deflate_generic_decompress(req);
}
dst_addr = sg_dma_address(req->dst);
- dev_dbg(dev, "dma_map_sg, dst_addr %llx, nr_sgs %d, req->dst %p,"
- " req->dlen %d, sg_dma_len(sg) %d\n", dst_addr, nr_sgs,
+ dev_dbg(dev, "map dst %llx req->dst %p dlen %d sg_len %d\n", dst_addr,
req->dst, req->dlen, sg_dma_len(req->dst));
ret = iaa_decompress(tfm, req, wq, src_addr, req->slen,
@@ -1636,15 +1720,16 @@ static int iaa_comp_adecompress(struct acomp_req *req)
if (ret == -EINPROGRESS)
return ret;
- if (ret != 0)
+ if (ret != 0 && ret != -EAGAIN)
dev_dbg(dev, "asynchronous decompress failed ret=%d\n", ret);
- dma_unmap_sg(dev, req->dst, sg_nents(req->dst), DMA_FROM_DEVICE);
-err_map_dst:
- dma_unmap_sg(dev, req->src, sg_nents(req->src), DMA_TO_DEVICE);
-out:
+ dma_unmap_sg(dev, req->dst, 1, DMA_FROM_DEVICE);
+ iaa_unmap_src(dev, req);
iaa_wq_put(wq);
+ if (ret == -EAGAIN)
+ ret = deflate_generic_decompress(req);
+
return ret;
}
@@ -1676,7 +1761,7 @@ static struct acomp_alg iaa_acomp_fixed_deflate = {
.cra_driver_name = "deflate-iaa",
.cra_flags = CRYPTO_ALG_ASYNC,
.cra_ctxsize = sizeof(struct iaa_compression_ctx),
- .cra_reqsize = sizeof(u32),
+ .cra_reqsize = sizeof(struct iaa_req_ctx),
.cra_module = THIS_MODULE,
.cra_priority = IAA_ALG_PRIORITY,
}
@@ -1875,6 +1960,12 @@ static int __init iaa_crypto_init_module(void)
goto err_aecs_init;
}
+ iaa_bounce_pool = mempool_create_page_pool(IAA_BOUNCE_POOL_SIZE, 0);
+ if (!iaa_bounce_pool) {
+ ret = -ENOMEM;
+ goto err_bounce_pool;
+ }
+
ret = idxd_driver_register(&iaa_crypto_driver);
if (ret) {
pr_debug("IAA wq sub-driver registration failed\n");
@@ -1908,6 +1999,9 @@ err_sync_attr_create:
err_verify_attr_create:
idxd_driver_unregister(&iaa_crypto_driver);
err_driver_reg:
+ mempool_destroy(iaa_bounce_pool);
+ iaa_bounce_pool = NULL;
+err_bounce_pool:
iaa_aecs_cleanup_fixed();
err_aecs_init:
@@ -1924,6 +2018,8 @@ static void __exit iaa_crypto_cleanup_module(void)
driver_remove_file(&iaa_crypto_driver.drv,
&driver_attr_verify_compress);
idxd_driver_unregister(&iaa_crypto_driver);
+ mempool_destroy(iaa_bounce_pool);
+ iaa_bounce_pool = NULL;
iaa_aecs_cleanup_fixed();
pr_debug("cleaned up\n");
diff --git a/drivers/crypto/intel/iaa/iaa_crypto_stats.c b/drivers/crypto/intel/iaa/iaa_crypto_stats.c
index f5cc3d29ca19..2f2ed88c8812 100644
--- a/drivers/crypto/intel/iaa/iaa_crypto_stats.c
+++ b/drivers/crypto/intel/iaa/iaa_crypto_stats.c
@@ -19,6 +19,7 @@
static atomic64_t total_comp_calls;
static atomic64_t total_decomp_calls;
+static atomic64_t total_sw_comp_calls;
static atomic64_t total_sw_decomp_calls;
static atomic64_t total_comp_bytes_out;
static atomic64_t total_decomp_bytes_in;
@@ -43,6 +44,11 @@ void update_total_decomp_calls(void)
atomic64_inc(&total_decomp_calls);
}
+void update_total_sw_comp_calls(void)
+{
+ atomic64_inc(&total_sw_comp_calls);
+}
+
void update_total_sw_decomp_calls(void)
{
atomic64_inc(&total_sw_decomp_calls);
@@ -104,6 +110,7 @@ static void reset_iaa_crypto_stats(void)
{
atomic64_set(&total_comp_calls, 0);
atomic64_set(&total_decomp_calls, 0);
+ atomic64_set(&total_sw_comp_calls, 0);
atomic64_set(&total_sw_decomp_calls, 0);
atomic64_set(&total_comp_bytes_out, 0);
atomic64_set(&total_decomp_bytes_in, 0);
@@ -174,6 +181,8 @@ static int global_stats_show(struct seq_file *m, void *v)
atomic64_read(&total_comp_calls));
seq_printf(m, " total_decomp_calls: %llu\n",
atomic64_read(&total_decomp_calls));
+ seq_printf(m, " total_sw_comp_calls: %llu\n",
+ atomic64_read(&total_sw_comp_calls));
seq_printf(m, " total_sw_decomp_calls: %llu\n",
atomic64_read(&total_sw_decomp_calls));
seq_printf(m, " total_comp_bytes_out: %llu\n",
diff --git a/drivers/crypto/intel/iaa/iaa_crypto_stats.h b/drivers/crypto/intel/iaa/iaa_crypto_stats.h
index 3787a5f507eb..6e0c6f9939bf 100644
--- a/drivers/crypto/intel/iaa/iaa_crypto_stats.h
+++ b/drivers/crypto/intel/iaa/iaa_crypto_stats.h
@@ -11,6 +11,7 @@ void iaa_crypto_debugfs_cleanup(void);
void update_total_comp_calls(void);
void update_total_comp_bytes_out(int n);
void update_total_decomp_calls(void);
+void update_total_sw_comp_calls(void);
void update_total_sw_decomp_calls(void);
void update_total_decomp_bytes_in(int n);
void update_completion_einval_errs(void);
@@ -29,6 +30,7 @@ static inline void iaa_crypto_debugfs_cleanup(void) {}
static inline void update_total_comp_calls(void) {}
static inline void update_total_comp_bytes_out(int n) {}
static inline void update_total_decomp_calls(void) {}
+static inline void update_total_sw_comp_calls(void) {}
static inline void update_total_sw_decomp_calls(void) {}
static inline void update_total_decomp_bytes_in(int n) {}
static inline void update_completion_einval_errs(void) {}
diff --git a/drivers/crypto/intel/ixp4xx/ixp4xx_crypto.c b/drivers/crypto/intel/ixp4xx/ixp4xx_crypto.c
index 5b90cf0fb0e4..fdda04672454 100644
--- a/drivers/crypto/intel/ixp4xx/ixp4xx_crypto.c
+++ b/drivers/crypto/intel/ixp4xx/ixp4xx_crypto.c
@@ -1591,6 +1591,7 @@ static const struct of_device_id ixp4xx_crypto_of_match[] = {
},
{},
};
+MODULE_DEVICE_TABLE(of, ixp4xx_crypto_of_match);
static struct platform_driver ixp_crypto_driver = {
.probe = ixp_crypto_probe,
diff --git a/drivers/crypto/intel/keembay/keembay-ocs-aes-core.c b/drivers/crypto/intel/keembay/keembay-ocs-aes-core.c
index 8a8f6c81e010..660830c36e14 100644
--- a/drivers/crypto/intel/keembay/keembay-ocs-aes-core.c
+++ b/drivers/crypto/intel/keembay/keembay-ocs-aes-core.c
@@ -11,6 +11,7 @@
#include <crypto/internal/aead.h>
#include <crypto/internal/skcipher.h>
#include <crypto/scatterwalk.h>
+#include <crypto/utils.h>
#include <linux/clk.h>
#include <linux/completion.h>
#include <linux/dma-mapping.h>
@@ -919,7 +920,7 @@ static int kmb_ocs_aead_run(struct aead_request *req)
/* For GCM decrypt, we have to compare in_tag with out_tag. */
if (rctx->instruction == OCS_DECRYPT) {
- rc = memcmp(rctx->in_tag, rctx->out_tag, tag_size) ?
+ rc = crypto_memneq(rctx->in_tag, rctx->out_tag, tag_size) ?
-EBADMSG : 0;
goto exit;
}
@@ -1541,7 +1542,7 @@ static int register_aes_algs(struct ocs_aes_dev *aes_dev)
/*
* If any algorithm fails to register, all preceding algorithms that
- * were successfully registered will be automatically unregistered.
+ * were registered in the same call are automatically unregistered.
*/
ret = crypto_engine_register_aeads(algs_aead, ARRAY_SIZE(algs_aead));
if (ret)
@@ -1549,7 +1550,7 @@ static int register_aes_algs(struct ocs_aes_dev *aes_dev)
ret = crypto_engine_register_skciphers(algs, ARRAY_SIZE(algs));
if (ret)
- crypto_engine_unregister_aeads(algs_aead, ARRAY_SIZE(algs));
+ crypto_engine_unregister_aeads(algs_aead, ARRAY_SIZE(algs_aead));
return ret;
}
@@ -1561,6 +1562,7 @@ static const struct of_device_id kmb_ocs_aes_of_match[] = {
},
{}
};
+MODULE_DEVICE_TABLE(of, kmb_ocs_aes_of_match);
static void kmb_ocs_aes_remove(struct platform_device *pdev)
{
@@ -1602,6 +1604,8 @@ static int kmb_ocs_aes_probe(struct platform_device *pdev)
if (IS_ERR(aes_dev->base_reg))
return PTR_ERR(aes_dev->base_reg);
+ init_completion(&aes_dev->irq_completion);
+
/* Get and request IRQ */
aes_dev->irq = platform_get_irq(pdev, 0);
if (aes_dev->irq < 0)
@@ -1609,18 +1613,14 @@ static int kmb_ocs_aes_probe(struct platform_device *pdev)
rc = devm_request_threaded_irq(dev, aes_dev->irq, ocs_aes_irq_handler,
NULL, 0, "keembay-ocs-aes", aes_dev);
- if (rc < 0) {
- dev_err(dev, "Could not request IRQ\n");
+ if (rc < 0)
return rc;
- }
INIT_LIST_HEAD(&aes_dev->list);
spin_lock(&ocs_aes.lock);
list_add_tail(&aes_dev->list, &ocs_aes.dev_list);
spin_unlock(&ocs_aes.lock);
- init_completion(&aes_dev->irq_completion);
-
/* Initialize crypto engine */
aes_dev->engine = crypto_engine_alloc_init(dev, true);
if (!aes_dev->engine) {
diff --git a/drivers/crypto/intel/keembay/keembay-ocs-ecc.c b/drivers/crypto/intel/keembay/keembay-ocs-ecc.c
index e61a95f66a0c..9bdee39dc4e1 100644
--- a/drivers/crypto/intel/keembay/keembay-ocs-ecc.c
+++ b/drivers/crypto/intel/keembay/keembay-ocs-ecc.c
@@ -900,10 +900,8 @@ static int kmb_ocs_ecc_probe(struct platform_device *pdev)
rc = devm_request_threaded_irq(dev, ecc_dev->irq, ocs_ecc_irq_handler,
NULL, 0, "keembay-ocs-ecc", ecc_dev);
- if (rc < 0) {
- dev_err(dev, "Could not request IRQ\n");
+ if (rc < 0)
goto list_del;
- }
/* Add device to the list of OCS ECC devices. */
spin_lock(&ocs_ecc.lock);
@@ -978,6 +976,7 @@ static const struct of_device_id kmb_ocs_ecc_of_match[] = {
},
{}
};
+MODULE_DEVICE_TABLE(of, kmb_ocs_ecc_of_match);
/* The OCS driver is a platform device. */
static struct platform_driver kmb_ocs_ecc_driver = {
diff --git a/drivers/crypto/intel/keembay/keembay-ocs-hcu-core.c b/drivers/crypto/intel/keembay/keembay-ocs-hcu-core.c
index 87b67060c77b..9a67bb4ecc82 100644
--- a/drivers/crypto/intel/keembay/keembay-ocs-hcu-core.c
+++ b/drivers/crypto/intel/keembay/keembay-ocs-hcu-core.c
@@ -1204,10 +1204,8 @@ static int kmb_ocs_hcu_probe(struct platform_device *pdev)
rc = devm_request_threaded_irq(&pdev->dev, hcu_dev->irq,
ocs_hcu_irq_handler, NULL, 0,
"keembay-ocs-hcu", hcu_dev);
- if (rc < 0) {
- dev_err(dev, "Could not request IRQ.\n");
+ if (rc < 0)
return rc;
- }
INIT_LIST_HEAD(&hcu_dev->list);
diff --git a/drivers/crypto/intel/keembay/ocs-aes.c b/drivers/crypto/intel/keembay/ocs-aes.c
index bb6f33f6b4d3..13ba7573617f 100644
--- a/drivers/crypto/intel/keembay/ocs-aes.c
+++ b/drivers/crypto/intel/keembay/ocs-aes.c
@@ -17,6 +17,7 @@
#include <crypto/aes.h>
#include <crypto/gcm.h>
+#include <crypto/utils.h>
#include "ocs-aes.h"
@@ -1283,7 +1284,7 @@ static inline int ccm_compare_tag_to_yr(struct ocs_aes_dev *aes_dev,
(i * sizeof(u32)));
}
- return memcmp(tag, yr, tag_size_bytes) ? -EBADMSG : 0;
+ return crypto_memneq(tag, yr, tag_size_bytes) ? -EBADMSG : 0;
}
/**
diff --git a/drivers/crypto/intel/qat/qat_common/adf_aer.c b/drivers/crypto/intel/qat/qat_common/adf_aer.c
index d58cd7fbf707..afded3030e9a 100644
--- a/drivers/crypto/intel/qat/qat_common/adf_aer.c
+++ b/drivers/crypto/intel/qat/qat_common/adf_aer.c
@@ -189,6 +189,8 @@ static void adf_device_reset_worker(struct work_struct *work)
queue_work(device_sriov_wq, &sriov_data.sriov_work);
if (wait_for_completion_timeout(&sriov_data.compl, wait_jiffies))
adf_pf2vf_notify_restarted(accel_dev);
+ else
+ cancel_work_sync(&sriov_data.sriov_work);
adf_dev_restarted_notify(accel_dev);
clear_bit(ADF_STATUS_RESTARTING, &accel_dev->status);
diff --git a/drivers/crypto/intel/qat/qat_common/adf_cfg.c b/drivers/crypto/intel/qat/qat_common/adf_cfg.c
index ea5d72d5090c..b88febf53a19 100644
--- a/drivers/crypto/intel/qat/qat_common/adf_cfg.c
+++ b/drivers/crypto/intel/qat/qat_common/adf_cfg.c
@@ -2,6 +2,7 @@
/* Copyright(c) 2014 - 2020 Intel Corporation */
#include <linux/mutex.h>
#include <linux/slab.h>
+#include <linux/string.h>
#include <linux/list.h>
#include <linux/seq_file.h>
#include "adf_accel_devices.h"
@@ -284,16 +285,13 @@ int adf_cfg_add_key_value_param(struct adf_accel_dev *accel_dev,
return -ENOMEM;
INIT_LIST_HEAD(&key_val->list);
- strscpy(key_val->key, key, sizeof(key_val->key));
+ strscpy(key_val->key, key);
if (type == ADF_DEC) {
snprintf(key_val->val, ADF_CFG_MAX_VAL_LEN_IN_BYTES,
"%ld", (*((long *)val)));
} else if (type == ADF_STR) {
- strscpy(key_val->val, (char *)val, sizeof(key_val->val));
- } else if (type == ADF_HEX) {
- snprintf(key_val->val, ADF_CFG_MAX_VAL_LEN_IN_BYTES,
- "0x%lx", (unsigned long)val);
+ strscpy(key_val->val, (char *)val);
} else {
dev_err(&GET_DEV(accel_dev), "Unknown type given.\n");
kfree(key_val);
@@ -350,7 +348,7 @@ int adf_cfg_section_add(struct adf_accel_dev *accel_dev, const char *name)
if (!sec)
return -ENOMEM;
- strscpy(sec->name, name, sizeof(sec->name));
+ strscpy(sec->name, name);
INIT_LIST_HEAD(&sec->param_head);
down_write(&cfg->lock);
list_add_tail(&sec->list, &cfg->sec_list);
diff --git a/drivers/crypto/intel/qat/qat_common/adf_cfg_common.h b/drivers/crypto/intel/qat/qat_common/adf_cfg_common.h
index d63f4dcccbb5..5922d018f5b9 100644
--- a/drivers/crypto/intel/qat/qat_common/adf_cfg_common.h
+++ b/drivers/crypto/intel/qat/qat_common/adf_cfg_common.h
@@ -28,7 +28,6 @@ enum adf_cfg_service_type {
enum adf_cfg_val_type {
ADF_DEC,
- ADF_HEX,
ADF_STR
};
diff --git a/drivers/crypto/intel/qat/qat_common/adf_cfg_services.c b/drivers/crypto/intel/qat/qat_common/adf_cfg_services.c
index 1af6da8b263f..f7237c7ef2b1 100644
--- a/drivers/crypto/intel/qat/qat_common/adf_cfg_services.c
+++ b/drivers/crypto/intel/qat/qat_common/adf_cfg_services.c
@@ -49,18 +49,17 @@ static_assert(sizeof(ADF_CFG_SYM ADF_SERVICES_DELIMITER
ADF_CFG_DCC) < ADF_CFG_MAX_VAL_LEN_IN_BYTES);
static int adf_service_string_to_mask(struct adf_accel_dev *accel_dev, const char *buf,
- size_t len, unsigned long *out_mask)
+ unsigned long *out_mask)
{
struct adf_hw_device_data *hw_data = GET_HW_DATA(accel_dev);
- char services[ADF_CFG_MAX_VAL_LEN_IN_BYTES] = { };
+ char services[ADF_CFG_MAX_VAL_LEN_IN_BYTES];
unsigned long mask = 0;
char *substr, *token;
int id, num_svc = 0;
- if (len > ADF_CFG_MAX_VAL_LEN_IN_BYTES - 1)
+ if (strscpy_pad(services, buf) < 0)
return -EINVAL;
- strscpy(services, buf, ADF_CFG_MAX_VAL_LEN_IN_BYTES);
substr = services;
while ((token = strsep(&substr, ADF_SERVICES_DELIMITER))) {
@@ -103,12 +102,12 @@ static int adf_service_mask_to_string(unsigned long mask, char *buf, size_t len)
}
int adf_parse_service_string(struct adf_accel_dev *accel_dev, const char *in,
- size_t in_len, char *out, size_t out_len)
+ char *out, size_t out_len)
{
unsigned long mask;
int ret;
- ret = adf_service_string_to_mask(accel_dev, in, in_len, &mask);
+ ret = adf_service_string_to_mask(accel_dev, in, &mask);
if (ret)
return ret;
@@ -121,7 +120,6 @@ int adf_parse_service_string(struct adf_accel_dev *accel_dev, const char *in,
int adf_get_service_mask(struct adf_accel_dev *accel_dev, unsigned long *mask)
{
char services[ADF_CFG_MAX_VAL_LEN_IN_BYTES] = { };
- size_t len;
int ret;
ret = adf_cfg_get_param_value(accel_dev, ADF_GENERAL_SEC,
@@ -132,8 +130,7 @@ int adf_get_service_mask(struct adf_accel_dev *accel_dev, unsigned long *mask)
return ret;
}
- len = strnlen(services, ADF_CFG_MAX_VAL_LEN_IN_BYTES);
- ret = adf_service_string_to_mask(accel_dev, services, len, mask);
+ ret = adf_service_string_to_mask(accel_dev, services, mask);
if (ret)
dev_err(&GET_DEV(accel_dev), "Invalid value of %s param: %s\n",
ADF_SERVICES_ENABLED, services);
diff --git a/drivers/crypto/intel/qat/qat_common/adf_cfg_services.h b/drivers/crypto/intel/qat/qat_common/adf_cfg_services.h
index 913d717280af..89be2f2c7233 100644
--- a/drivers/crypto/intel/qat/qat_common/adf_cfg_services.h
+++ b/drivers/crypto/intel/qat/qat_common/adf_cfg_services.h
@@ -35,7 +35,7 @@ enum {
#define MAX_NUM_CONCURR_SVC ADF_THREE_SERVICES
int adf_parse_service_string(struct adf_accel_dev *accel_dev, const char *in,
- size_t in_len, char *out, size_t out_len);
+ char *out, size_t out_len);
int adf_get_service_enabled(struct adf_accel_dev *accel_dev);
int adf_get_service_mask(struct adf_accel_dev *accel_dev, unsigned long *mask);
enum adf_cfg_service_type adf_srv_to_cfg_svc_type(enum adf_base_services svc);
diff --git a/drivers/crypto/intel/qat/qat_common/adf_gen2_config.c b/drivers/crypto/intel/qat/qat_common/adf_gen2_config.c
index c27ff6d18e11..57025bffee73 100644
--- a/drivers/crypto/intel/qat/qat_common/adf_gen2_config.c
+++ b/drivers/crypto/intel/qat/qat_common/adf_gen2_config.c
@@ -155,12 +155,8 @@ static int adf_gen2_comp_dev_config(struct adf_accel_dev *accel_dev)
}
val = i;
- ret = adf_cfg_add_key_value_param(accel_dev, ADF_KERNEL_SEC, ADF_NUM_DC,
- &val, ADF_DEC);
- if (ret)
- return ret;
-
- return ret;
+ return adf_cfg_add_key_value_param(accel_dev, ADF_KERNEL_SEC,
+ ADF_NUM_DC, &val, ADF_DEC);
err:
dev_err(&GET_DEV(accel_dev), "Failed to add configuration for compression\n");
diff --git a/drivers/crypto/intel/qat/qat_common/adf_mstate_mgr.c b/drivers/crypto/intel/qat/qat_common/adf_mstate_mgr.c
index f9017e03ec0f..32aeb795cc03 100644
--- a/drivers/crypto/intel/qat/qat_common/adf_mstate_mgr.c
+++ b/drivers/crypto/intel/qat/qat_common/adf_mstate_mgr.c
@@ -2,6 +2,7 @@
/* Copyright(c) 2024 Intel Corporation */
#include <linux/slab.h>
+#include <linux/string.h>
#include <linux/types.h>
#include "adf_mstate_mgr.h"
@@ -158,7 +159,7 @@ static struct adf_mstate_sect_h *adf_mstate_sect_add_header(struct adf_mstate_mg
return NULL;
}
- strscpy(sect->id, id, sizeof(sect->id));
+ strscpy(sect->id, id);
sect->size = 0;
sect->sub_sects = 0;
mgr->state += sizeof(*sect);
diff --git a/drivers/crypto/intel/qat/qat_common/adf_sysfs.c b/drivers/crypto/intel/qat/qat_common/adf_sysfs.c
index 79c63dfa8ff3..8daa69a76b01 100644
--- a/drivers/crypto/intel/qat/qat_common/adf_sysfs.c
+++ b/drivers/crypto/intel/qat/qat_common/adf_sysfs.c
@@ -125,7 +125,7 @@ static ssize_t cfg_services_store(struct device *dev, struct device_attribute *a
if (!accel_dev)
return -EINVAL;
- ret = adf_parse_service_string(accel_dev, buf, count, services,
+ ret = adf_parse_service_string(accel_dev, buf, services,
ADF_CFG_MAX_VAL_LEN_IN_BYTES);
if (ret)
return ret;
diff --git a/drivers/crypto/intel/qat/qat_common/adf_transport_debug.c b/drivers/crypto/intel/qat/qat_common/adf_transport_debug.c
index a8f853516a3f..fc5d88a2bb17 100644
--- a/drivers/crypto/intel/qat/qat_common/adf_transport_debug.c
+++ b/drivers/crypto/intel/qat/qat_common/adf_transport_debug.c
@@ -2,6 +2,7 @@
/* Copyright(c) 2014 - 2020 Intel Corporation */
#include <linux/mutex.h>
#include <linux/slab.h>
+#include <linux/string.h>
#include <linux/seq_file.h>
#include "adf_accel_devices.h"
#include "adf_transport_internal.h"
@@ -103,7 +104,7 @@ int adf_ring_debugfs_add(struct adf_etr_ring_data *ring, const char *name)
if (!ring_debug)
return -ENOMEM;
- strscpy(ring_debug->ring_name, name, sizeof(ring_debug->ring_name));
+ strscpy(ring_debug->ring_name, name);
snprintf(entry_name, sizeof(entry_name), "ring_%02d",
ring->ring_number);
diff --git a/drivers/crypto/intel/qat/qat_common/qat_algs.c b/drivers/crypto/intel/qat/qat_common/qat_algs.c
index 7f638a62e3ad..91663805d9e6 100644
--- a/drivers/crypto/intel/qat/qat_common/qat_algs.c
+++ b/drivers/crypto/intel/qat/qat_common/qat_algs.c
@@ -405,6 +405,7 @@ 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,
diff --git a/drivers/crypto/intel/qat/qat_common/qat_compression.c b/drivers/crypto/intel/qat/qat_common/qat_compression.c
index 1424d7a9bcd3..8129ad0c32d8 100644
--- a/drivers/crypto/intel/qat/qat_common/qat_compression.c
+++ b/drivers/crypto/intel/qat/qat_common/qat_compression.c
@@ -2,6 +2,7 @@
/* Copyright(c) 2022 Intel Corporation */
#include <linux/module.h>
#include <linux/slab.h>
+#include <linux/string.h>
#include "adf_accel_devices.h"
#include "adf_common_drv.h"
#include "adf_transport.h"
@@ -144,7 +145,7 @@ static int qat_compression_create_instances(struct adf_accel_dev *accel_dev)
int i;
INIT_LIST_HEAD(&accel_dev->compression_list);
- strscpy(key, ADF_NUM_DC, sizeof(key));
+ strscpy(key, ADF_NUM_DC);
ret = adf_cfg_get_param_value(accel_dev, SEC, key, val);
if (ret)
return ret;
diff --git a/drivers/crypto/marvell/cesa/cesa.c b/drivers/crypto/marvell/cesa/cesa.c
index 75d8ba23d9a2..564b09773507 100644
--- a/drivers/crypto/marvell/cesa/cesa.c
+++ b/drivers/crypto/marvell/cesa/cesa.c
@@ -366,6 +366,8 @@ static int mv_cesa_dev_dma_init(struct mv_cesa_dev *cesa)
return 0;
}
+static void mv_cesa_release_sram(void *data);
+
static int mv_cesa_get_sram(struct platform_device *pdev, int idx)
{
struct mv_cesa_dev *cesa = platform_get_drvdata(pdev);
@@ -378,11 +380,13 @@ static int mv_cesa_get_sram(struct platform_device *pdev, int idx)
engine->sram_pool = gen_pool_dma_alloc(engine->pool,
cesa->sram_size,
&engine->sram_dma);
- if (engine->sram_pool)
- return 0;
+ if (!engine->sram_pool) {
+ engine->pool = NULL;
+ return -ENOMEM;
+ }
- engine->pool = NULL;
- return -ENOMEM;
+ return devm_add_action_or_reset(cesa->dev, mv_cesa_release_sram,
+ engine);
}
engine->sram = devm_platform_get_and_ioremap_resource(pdev, idx, &res);
@@ -395,13 +399,13 @@ static int mv_cesa_get_sram(struct platform_device *pdev, int idx)
if (dma_mapping_error(cesa->dev, engine->sram_dma))
return -ENOMEM;
- return 0;
+ return devm_add_action_or_reset(cesa->dev, mv_cesa_release_sram, engine);
}
-static void mv_cesa_put_sram(struct platform_device *pdev, int idx)
+static void mv_cesa_release_sram(void *data)
{
- struct mv_cesa_dev *cesa = platform_get_drvdata(pdev);
- struct mv_cesa_engine *engine = &cesa->engines[idx];
+ struct mv_cesa_engine *engine = data;
+ struct mv_cesa_dev *cesa = engine->cesa;
if (engine->pool)
gen_pool_free(engine->pool, (unsigned long)engine->sram_pool,
@@ -465,17 +469,16 @@ static int mv_cesa_probe(struct platform_device *pdev)
char res_name[16];
engine->id = i;
+ engine->cesa = cesa;
spin_lock_init(&engine->lock);
ret = mv_cesa_get_sram(pdev, i);
if (ret)
- goto err_cleanup;
+ return ret;
irq = platform_get_irq(pdev, i);
- if (irq < 0) {
- ret = irq;
- goto err_cleanup;
- }
+ if (irq < 0)
+ return irq;
engine->irq = irq;
@@ -487,18 +490,14 @@ static int mv_cesa_probe(struct platform_device *pdev)
engine->clk = devm_clk_get_optional_enabled(dev, res_name);
if (IS_ERR(engine->clk)) {
engine->clk = devm_clk_get_optional_enabled(dev, NULL);
- if (IS_ERR(engine->clk)) {
- ret = PTR_ERR(engine->clk);
- goto err_cleanup;
- }
+ if (IS_ERR(engine->clk))
+ return PTR_ERR(engine->clk);
}
snprintf(res_name, sizeof(res_name), "cesaz%u", i);
engine->zclk = devm_clk_get_optional_enabled(dev, res_name);
- if (IS_ERR(engine->zclk)) {
- ret = PTR_ERR(engine->zclk);
- goto err_cleanup;
- }
+ if (IS_ERR(engine->zclk))
+ return PTR_ERR(engine->zclk);
engine->regs = cesa->regs + CESA_ENGINE_OFF(i);
@@ -516,7 +515,7 @@ static int mv_cesa_probe(struct platform_device *pdev)
dev_name(&pdev->dev),
engine);
if (ret)
- goto err_cleanup;
+ return ret;
/* Set affinity */
cpu = cpumask_local_spread(engine->id, NUMA_NO_NODE);
@@ -532,29 +531,21 @@ static int mv_cesa_probe(struct platform_device *pdev)
ret = mv_cesa_add_algs(cesa);
if (ret) {
cesa_dev = NULL;
- goto err_cleanup;
+ return ret;
}
dev_info(dev, "CESA device successfully registered\n");
return 0;
-
-err_cleanup:
- for (i = 0; i < caps->nengines; i++)
- mv_cesa_put_sram(pdev, i);
-
- return ret;
}
static void mv_cesa_remove(struct platform_device *pdev)
{
struct mv_cesa_dev *cesa = platform_get_drvdata(pdev);
- int i;
mv_cesa_remove_algs(cesa);
- for (i = 0; i < cesa->caps->nengines; i++)
- mv_cesa_put_sram(pdev, i);
+ cesa_dev = NULL;
}
static const struct platform_device_id mv_cesa_plat_id_table[] = {
diff --git a/drivers/crypto/marvell/cesa/cesa.h b/drivers/crypto/marvell/cesa/cesa.h
index 18f9f28040a6..44351b252861 100644
--- a/drivers/crypto/marvell/cesa/cesa.h
+++ b/drivers/crypto/marvell/cesa/cesa.h
@@ -415,6 +415,7 @@ struct mv_cesa_dev_dma {
* @zclk: engine zclk
* @max_req_len: maximum chunk length (useful to create the TDMA chain)
* @int_mask: interrupt mask cache
+ * @cesa: back-pointer to the parent CESA device
* @pool: memory pool pointing to the memory region reserved in
* SRAM
* @queue: fifo of the pending crypto requests
@@ -441,6 +442,7 @@ struct mv_cesa_engine {
struct clk *zclk;
size_t max_req_len;
u32 int_mask;
+ struct mv_cesa_dev *cesa;
struct gen_pool *pool;
struct crypto_queue queue;
atomic_t load;
diff --git a/drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c b/drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c
index 205579a6ba2b..c66cd322994f 100644
--- a/drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c
+++ b/drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c
@@ -99,39 +99,31 @@ static int dev_supports_eng_type(struct otx_cpt_eng_grps *eng_grps,
static void set_ucode_filename(struct otx_cpt_ucode *ucode,
const char *filename)
{
- strscpy(ucode->filename, filename, OTX_CPT_UCODE_NAME_LENGTH);
+ strscpy(ucode->filename, filename);
}
static char *get_eng_type_str(int eng_type)
{
- char *str = "unknown";
-
switch (eng_type) {
case OTX_CPT_SE_TYPES:
- str = "SE";
- break;
-
+ return "SE";
case OTX_CPT_AE_TYPES:
- str = "AE";
- break;
+ return "AE";
+ default:
+ return "unknown";
}
- return str;
}
static char *get_ucode_type_str(int ucode_type)
{
- char *str = "unknown";
-
switch (ucode_type) {
case (1 << OTX_CPT_SE_TYPES):
- str = "SE";
- break;
-
+ return "SE";
case (1 << OTX_CPT_AE_TYPES):
- str = "AE";
- break;
+ return "AE";
+ default:
+ return "unknown";
}
- return str;
}
static int get_ucode_type(struct otx_cpt_ucode_hdr *ucode_hdr, int *ucode_type)
@@ -140,7 +132,7 @@ static int get_ucode_type(struct otx_cpt_ucode_hdr *ucode_hdr, int *ucode_type)
u32 i, val = 0;
u8 nn;
- strscpy(tmp_ver_str, ucode_hdr->ver_str, OTX_CPT_UCODE_VER_STR_SZ);
+ strscpy(tmp_ver_str, ucode_hdr->ver_str);
for (i = 0; i < strlen(tmp_ver_str); i++)
tmp_ver_str[i] = tolower(tmp_ver_str[i]);
diff --git a/drivers/crypto/marvell/octeontx2/otx2_cpt_mbox_common.c b/drivers/crypto/marvell/octeontx2/otx2_cpt_mbox_common.c
index 95f3de3a34eb..1542a110ba37 100644
--- a/drivers/crypto/marvell/octeontx2/otx2_cpt_mbox_common.c
+++ b/drivers/crypto/marvell/octeontx2/otx2_cpt_mbox_common.c
@@ -235,7 +235,6 @@ int otx2_cpt_lf_reset_msg(struct otx2_cptlfs_info *lfs, int slot)
struct otx2_mbox *mbox = lfs->mbox;
struct pci_dev *pdev = lfs->pdev;
struct cpt_lf_rst_req *req;
- int ret;
req = (struct cpt_lf_rst_req *)otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req),
sizeof(struct msg_rsp));
@@ -248,11 +247,7 @@ int otx2_cpt_lf_reset_msg(struct otx2_cptlfs_info *lfs, int slot)
req->hdr.sig = OTX2_MBOX_REQ_SIG;
req->hdr.pcifunc = 0;
req->slot = slot;
- ret = otx2_cpt_send_mbox_msg(mbox, pdev);
- if (ret)
- return ret;
-
- return ret;
+ return otx2_cpt_send_mbox_msg(mbox, pdev);
}
EXPORT_SYMBOL_NS_GPL(otx2_cpt_lf_reset_msg, "CRYPTO_DEV_OCTEONTX2_CPT");
diff --git a/drivers/crypto/marvell/octeontx2/otx2_cptpf_main.c b/drivers/crypto/marvell/octeontx2/otx2_cptpf_main.c
index f6f47f4e5d83..79f6c2bb9d8b 100644
--- a/drivers/crypto/marvell/octeontx2/otx2_cptpf_main.c
+++ b/drivers/crypto/marvell/octeontx2/otx2_cptpf_main.c
@@ -430,11 +430,8 @@ static int cptpf_register_afpf_mbox_intr(struct otx2_cptpf_dev *cptpf)
/* Register AF-PF mailbox interrupt handler */
ret = devm_request_irq(dev, irq, otx2_cptpf_afpf_mbox_intr, 0,
"CPTAFPF Mbox", cptpf);
- if (ret) {
- dev_err(dev,
- "IRQ registration failed for PFAF mbox irq\n");
+ if (ret)
return ret;
- }
/* Clear interrupt if any, to avoid spurious interrupts */
otx2_cpt_write64(cptpf->reg_base, BLKADDR_RVUM, 0, RVU_PF_INT, 0x1ULL);
/* Enable AF-PF interrupt */
diff --git a/drivers/crypto/marvell/octeontx2/otx2_cptpf_ucode.c b/drivers/crypto/marvell/octeontx2/otx2_cptpf_ucode.c
index 9b0887d7e62c..465f00e74623 100644
--- a/drivers/crypto/marvell/octeontx2/otx2_cptpf_ucode.c
+++ b/drivers/crypto/marvell/octeontx2/otx2_cptpf_ucode.c
@@ -74,7 +74,7 @@ static int is_2nd_ucode_used(struct otx2_cpt_eng_grp_info *eng_grp)
static void set_ucode_filename(struct otx2_cpt_ucode *ucode,
const char *filename)
{
- strscpy(ucode->filename, filename, OTX2_CPT_NAME_LENGTH);
+ strscpy(ucode->filename, filename);
}
static char *get_eng_type_str(int eng_type)
@@ -130,7 +130,7 @@ static int get_ucode_type(struct device *dev,
int i, val = 0;
u8 nn;
- strscpy(tmp_ver_str, ucode_hdr->ver_str, OTX2_CPT_UCODE_VER_STR_SZ);
+ strscpy(tmp_ver_str, ucode_hdr->ver_str);
for (i = 0; i < strlen(tmp_ver_str); i++)
tmp_ver_str[i] = tolower(tmp_ver_str[i]);
diff --git a/drivers/crypto/mxs-dcp.c b/drivers/crypto/mxs-dcp.c
index 133ebc998236..c75a06999787 100644
--- a/drivers/crypto/mxs-dcp.c
+++ b/drivers/crypto/mxs-dcp.c
@@ -353,7 +353,7 @@ static int mxs_dcp_aes_block_crypt(struct crypto_async_request *arq)
for_each_sg(req->src, src, sg_nents(req->src), i) {
src_buf = sg_virt(src);
- len = sg_dma_len(src);
+ len = src->length;
tlen += len;
limit_hit = tlen > req->cryptlen;
@@ -1085,17 +1085,13 @@ static int mxs_dcp_probe(struct platform_device *pdev)
ret = devm_request_irq(dev, dcp_vmi_irq, mxs_dcp_irq, 0,
"dcp-vmi-irq", sdcp);
- if (ret) {
- dev_err(dev, "Failed to claim DCP VMI IRQ!\n");
+ if (ret)
return ret;
- }
ret = devm_request_irq(dev, dcp_irq, mxs_dcp_irq, 0,
"dcp-irq", sdcp);
- if (ret) {
- dev_err(dev, "Failed to claim DCP IRQ!\n");
+ if (ret)
return ret;
- }
/* Allocate coherent helper block. */
sdcp->coh = devm_kzalloc(dev, sizeof(*sdcp->coh) + DCP_ALIGNMENT,
diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c
index f31555c0d715..d40074e5a142 100644
--- a/drivers/crypto/omap-aes.c
+++ b/drivers/crypto/omap-aes.c
@@ -27,7 +27,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/scatterlist.h>
@@ -952,65 +951,8 @@ static const struct of_device_id omap_aes_of_match[] = {
{},
};
MODULE_DEVICE_TABLE(of, omap_aes_of_match);
-
-static int omap_aes_get_res_of(struct omap_aes_dev *dd,
- struct device *dev, struct resource *res)
-{
- struct device_node *node = dev->of_node;
- int err = 0;
-
- dd->pdata = of_device_get_match_data(dev);
- if (!dd->pdata) {
- dev_err(dev, "no compatible OF match\n");
- err = -EINVAL;
- goto err;
- }
-
- err = of_address_to_resource(node, 0, res);
- if (err < 0) {
- dev_err(dev, "can't translate OF node address\n");
- err = -EINVAL;
- goto err;
- }
-
-err:
- return err;
-}
-#else
-static const struct of_device_id omap_aes_of_match[] = {
- {},
-};
-
-static int omap_aes_get_res_of(struct omap_aes_dev *dd,
- struct device *dev, struct resource *res)
-{
- return -EINVAL;
-}
#endif
-static int omap_aes_get_res_pdev(struct omap_aes_dev *dd,
- struct platform_device *pdev, struct resource *res)
-{
- struct device *dev = &pdev->dev;
- struct resource *r;
- int err = 0;
-
- /* Get the base address */
- r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!r) {
- dev_err(dev, "no MEM resource info\n");
- err = -ENODEV;
- goto err;
- }
- memcpy(res, r, sizeof(*res));
-
- /* Only OMAP2/3 can be non-DT */
- dd->pdata = &omap_aes_pdata_omap2;
-
-err:
- return err;
-}
-
static ssize_t fallback_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
@@ -1109,10 +1051,15 @@ static int omap_aes_probe(struct platform_device *pdev)
struct omap_aes_dev *dd;
struct skcipher_engine_alg *algp;
struct aead_engine_alg *aalg;
- struct resource res;
+ struct resource *res;
+ void __iomem *io_base;
int err = -ENOMEM, i, j, irq = -1;
u32 reg;
+ io_base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
+ if (IS_ERR(io_base))
+ return PTR_ERR(io_base);
+
dd = devm_kzalloc(dev, sizeof(struct omap_aes_dev), GFP_KERNEL);
if (dd == NULL) {
dev_err(dev, "unable to alloc data struct.\n");
@@ -1123,17 +1070,12 @@ static int omap_aes_probe(struct platform_device *pdev)
aead_init_queue(&dd->aead_queue, OMAP_AES_QUEUE_LENGTH);
- err = (dev->of_node) ? omap_aes_get_res_of(dd, dev, &res) :
- omap_aes_get_res_pdev(dd, pdev, &res);
- if (err)
- goto err_res;
+ dd->pdata = device_get_match_data(dev);
+ if (!dd->pdata)
+ dd->pdata = &omap_aes_pdata_omap2;
- dd->io_base = devm_ioremap_resource(dev, &res);
- if (IS_ERR(dd->io_base)) {
- err = PTR_ERR(dd->io_base);
- goto err_res;
- }
- dd->phys_base = res.start;
+ dd->io_base = io_base;
+ dd->phys_base = res->start;
pm_runtime_use_autosuspend(dev);
pm_runtime_set_autosuspend_delay(dev, DEFAULT_AUTOSUSPEND_DELAY);
@@ -1172,10 +1114,8 @@ static int omap_aes_probe(struct platform_device *pdev)
err = devm_request_irq(dev, irq, omap_aes_irq, 0,
dev_name(dev), dd);
- if (err) {
- dev_err(dev, "Unable to grab omap-aes IRQ\n");
+ if (err)
goto err_irq;
- }
}
spin_lock_init(&dd->lock);
@@ -1244,8 +1184,6 @@ err_irq:
cancel_work_sync(&dd->done_task);
err_pm_disable:
pm_runtime_disable(dev);
-err_res:
- dd = NULL;
err_data:
dev_err(dev, "initialization failed.\n");
return err;
@@ -1294,7 +1232,7 @@ static struct platform_driver omap_aes_driver = {
.driver = {
.name = "omap-aes",
.pm = &omap_aes_pm_ops,
- .of_match_table = omap_aes_of_match,
+ .of_match_table = of_match_ptr(omap_aes_of_match),
.dev_groups = omap_aes_groups,
},
};
diff --git a/drivers/crypto/omap-des.c b/drivers/crypto/omap-des.c
index dfaf831dd8ec..3b7104cb4487 100644
--- a/drivers/crypto/omap-des.c
+++ b/drivers/crypto/omap-des.c
@@ -1017,10 +1017,8 @@ static int omap_des_probe(struct platform_device *pdev)
err = devm_request_irq(dev, irq, omap_des_irq, 0,
dev_name(dev), dd);
- if (err) {
- dev_err(dev, "Unable to grab omap-des IRQ\n");
+ if (err)
goto err_irq;
- }
}
diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c
index be1ac640ee59..6d2dd0b88f15 100644
--- a/drivers/crypto/omap-sham.c
+++ b/drivers/crypto/omap-sham.c
@@ -30,8 +30,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/of_irq.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/scatterlist.h>
@@ -1896,79 +1894,8 @@ static const struct of_device_id omap_sham_of_match[] = {
{},
};
MODULE_DEVICE_TABLE(of, omap_sham_of_match);
-
-static int omap_sham_get_res_of(struct omap_sham_dev *dd,
- struct device *dev, struct resource *res)
-{
- struct device_node *node = dev->of_node;
- int err = 0;
-
- dd->pdata = of_device_get_match_data(dev);
- if (!dd->pdata) {
- dev_err(dev, "no compatible OF match\n");
- err = -EINVAL;
- goto err;
- }
-
- err = of_address_to_resource(node, 0, res);
- if (err < 0) {
- dev_err(dev, "can't translate OF node address\n");
- err = -EINVAL;
- goto err;
- }
-
- dd->irq = irq_of_parse_and_map(node, 0);
- if (!dd->irq) {
- dev_err(dev, "can't translate OF irq value\n");
- err = -EINVAL;
- goto err;
- }
-
-err:
- return err;
-}
-#else
-static const struct of_device_id omap_sham_of_match[] = {
- {},
-};
-
-static int omap_sham_get_res_of(struct omap_sham_dev *dd,
- struct device *dev, struct resource *res)
-{
- return -EINVAL;
-}
#endif
-static int omap_sham_get_res_pdev(struct omap_sham_dev *dd,
- struct platform_device *pdev, struct resource *res)
-{
- struct device *dev = &pdev->dev;
- struct resource *r;
- int err = 0;
-
- /* Get the base address */
- r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!r) {
- dev_err(dev, "no MEM resource info\n");
- err = -ENODEV;
- goto err;
- }
- memcpy(res, r, sizeof(*res));
-
- /* Get the IRQ */
- dd->irq = platform_get_irq(pdev, 0);
- if (dd->irq < 0) {
- err = dd->irq;
- goto err;
- }
-
- /* Only OMAP2/3 can be non-DT */
- dd->pdata = &omap_sham_pdata_omap2;
-
-err:
- return err;
-}
-
static ssize_t fallback_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
@@ -2060,11 +1987,20 @@ static int omap_sham_probe(struct platform_device *pdev)
{
struct omap_sham_dev *dd;
struct device *dev = &pdev->dev;
- struct resource res;
+ void __iomem *io_base;
+ struct resource *res;
dma_cap_mask_t mask;
- int err, i, j;
+ int err, i, j, irq;
u32 rev;
+ io_base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
+ if (IS_ERR(io_base))
+ return PTR_ERR(io_base);
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0)
+ return irq;
+
dd = devm_kzalloc(dev, sizeof(struct omap_sham_dev), GFP_KERNEL);
if (dd == NULL) {
dev_err(dev, "unable to alloc data struct.\n");
@@ -2078,25 +2014,18 @@ static int omap_sham_probe(struct platform_device *pdev)
INIT_WORK(&dd->done_task, omap_sham_done_task);
crypto_init_queue(&dd->queue, OMAP_SHAM_QUEUE_LENGTH);
- err = (dev->of_node) ? omap_sham_get_res_of(dd, dev, &res) :
- omap_sham_get_res_pdev(dd, pdev, &res);
- if (err)
- goto data_err;
+ dd->pdata = device_get_match_data(dev);
+ if (!dd->pdata)
+ dd->pdata = &omap_sham_pdata_omap2;
- dd->io_base = devm_ioremap_resource(dev, &res);
- if (IS_ERR(dd->io_base)) {
- err = PTR_ERR(dd->io_base);
- goto data_err;
- }
- dd->phys_base = res.start;
+ dd->irq = irq;
+ dd->io_base = io_base;
+ dd->phys_base = res->start;
err = devm_request_irq(dev, dd->irq, dd->pdata->intr_hdlr,
IRQF_TRIGGER_NONE, dev_name(dev), dd);
- if (err) {
- dev_err(dev, "unable to request irq %d, err = %d\n",
- dd->irq, err);
+ if (err)
goto data_err;
- }
dma_cap_zero(mask);
dma_cap_set(DMA_SLAVE, mask);
@@ -2213,7 +2142,7 @@ static struct platform_driver omap_sham_driver = {
.remove = omap_sham_remove,
.driver = {
.name = "omap-sham",
- .of_match_table = omap_sham_of_match,
+ .of_match_table = of_match_ptr(omap_sham_of_match),
.dev_groups = omap_sham_groups,
},
};
diff --git a/drivers/crypto/qce/aead.c b/drivers/crypto/qce/aead.c
index 9cb11fada2c4..a9642c67f476 100644
--- a/drivers/crypto/qce/aead.c
+++ b/drivers/crypto/qce/aead.c
@@ -9,8 +9,6 @@
#include <crypto/gcm.h>
#include <crypto/authenc.h>
#include <crypto/internal/aead.h>
-#include <crypto/internal/des.h>
-#include <crypto/sha1.h>
#include <crypto/sha2.h>
#include <crypto/scatterwalk.h>
#include "aead.h"
@@ -198,7 +196,7 @@ qce_aead_ccm_prepare_buf_assoclen(struct aead_request *req)
/* Get the msg */
msg_sg = scatterwalk_ffwd(__sg, req->src, req->assoclen);
- rctx->adata = kzalloc((ALIGN(assoclen, 16) + MAX_CCM_ADATA_HEADER_LEN) *
+ rctx->adata = kzalloc(ALIGN(assoclen + MAX_CCM_ADATA_HEADER_LEN, 16) *
sizeof(unsigned char), GFP_ATOMIC);
if (!rctx->adata)
return -ENOMEM;
@@ -592,7 +590,6 @@ static int qce_aead_setkey(struct crypto_aead *tfm, const u8 *key, unsigned int
struct qce_aead_ctx *ctx = crypto_aead_ctx(tfm);
struct crypto_authenc_keys authenc_keys;
unsigned long flags = to_aead_tmpl(tfm)->alg_flags;
- u32 _key[6];
int err;
err = crypto_authenc_extractkeys(&authenc_keys, key, keylen);
@@ -603,26 +600,7 @@ static int qce_aead_setkey(struct crypto_aead *tfm, const u8 *key, unsigned int
authenc_keys.authkeylen > QCE_MAX_KEY_SIZE)
return -EINVAL;
- if (IS_DES(flags)) {
- err = verify_aead_des_key(tfm, authenc_keys.enckey, authenc_keys.enckeylen);
- if (err)
- return err;
- } else if (IS_3DES(flags)) {
- err = verify_aead_des3_key(tfm, authenc_keys.enckey, authenc_keys.enckeylen);
- if (err)
- return err;
- /*
- * The crypto engine does not support any two keys
- * being the same for triple des algorithms. The
- * verify_skcipher_des3_key does not check for all the
- * below conditions. Schedule fallback in this case.
- */
- memcpy(_key, authenc_keys.enckey, DES3_EDE_KEY_SIZE);
- if (!((_key[0] ^ _key[2]) | (_key[1] ^ _key[3])) ||
- !((_key[2] ^ _key[4]) | (_key[3] ^ _key[5])) ||
- !((_key[0] ^ _key[4]) | (_key[1] ^ _key[5])))
- ctx->need_fallback = true;
- } else if (IS_AES(flags)) {
+ if (IS_AES(flags)) {
/* No random key sizes */
if (authenc_keys.enckeylen != AES_KEYSIZE_128 &&
authenc_keys.enckeylen != AES_KEYSIZE_192 &&
@@ -694,38 +672,6 @@ struct qce_aead_def {
static const struct qce_aead_def aead_def[] = {
{
- .flags = QCE_ALG_DES | QCE_MODE_CBC | QCE_HASH_SHA1_HMAC,
- .name = "authenc(hmac(sha1),cbc(des))",
- .drv_name = "authenc-hmac-sha1-cbc-des-qce",
- .blocksize = DES_BLOCK_SIZE,
- .ivsize = DES_BLOCK_SIZE,
- .maxauthsize = SHA1_DIGEST_SIZE,
- },
- {
- .flags = QCE_ALG_3DES | QCE_MODE_CBC | QCE_HASH_SHA1_HMAC,
- .name = "authenc(hmac(sha1),cbc(des3_ede))",
- .drv_name = "authenc-hmac-sha1-cbc-3des-qce",
- .blocksize = DES3_EDE_BLOCK_SIZE,
- .ivsize = DES3_EDE_BLOCK_SIZE,
- .maxauthsize = SHA1_DIGEST_SIZE,
- },
- {
- .flags = QCE_ALG_DES | QCE_MODE_CBC | QCE_HASH_SHA256_HMAC,
- .name = "authenc(hmac(sha256),cbc(des))",
- .drv_name = "authenc-hmac-sha256-cbc-des-qce",
- .blocksize = DES_BLOCK_SIZE,
- .ivsize = DES_BLOCK_SIZE,
- .maxauthsize = SHA256_DIGEST_SIZE,
- },
- {
- .flags = QCE_ALG_3DES | QCE_MODE_CBC | QCE_HASH_SHA256_HMAC,
- .name = "authenc(hmac(sha256),cbc(des3_ede))",
- .drv_name = "authenc-hmac-sha256-cbc-3des-qce",
- .blocksize = DES3_EDE_BLOCK_SIZE,
- .ivsize = DES3_EDE_BLOCK_SIZE,
- .maxauthsize = SHA256_DIGEST_SIZE,
- },
- {
.flags = QCE_ALG_AES | QCE_MODE_CBC | QCE_HASH_SHA256_HMAC,
.name = "authenc(hmac(sha256),cbc(aes))",
.drv_name = "authenc-hmac-sha256-cbc-aes-qce",
diff --git a/drivers/crypto/qce/common.c b/drivers/crypto/qce/common.c
index 54a78a57f630..3081d765a0f2 100644
--- a/drivers/crypto/qce/common.c
+++ b/drivers/crypto/qce/common.c
@@ -8,7 +8,6 @@
#include <linux/interrupt.h>
#include <linux/types.h>
#include <crypto/scatterwalk.h>
-#include <crypto/sha1.h>
#include <crypto/sha2.h>
#include "cipher.h"
@@ -115,18 +114,16 @@ static u32 qce_auth_cfg(unsigned long flags, u32 key_size, u32 auth_size)
cfg |= AUTH_KEY_SZ_AES256 << AUTH_KEY_SIZE_SHIFT;
}
- if (IS_SHA1(flags) || IS_SHA1_HMAC(flags))
- cfg |= AUTH_SIZE_SHA1 << AUTH_SIZE_SHIFT;
- else if (IS_SHA256(flags) || IS_SHA256_HMAC(flags))
+ if (IS_SHA256(flags) || IS_SHA256_HMAC(flags))
cfg |= AUTH_SIZE_SHA256 << AUTH_SIZE_SHIFT;
else if (IS_CMAC(flags))
cfg |= AUTH_SIZE_ENUM_16_BYTES << AUTH_SIZE_SHIFT;
else if (IS_CCM(flags))
cfg |= (auth_size - 1) << AUTH_SIZE_SHIFT;
- if (IS_SHA1(flags) || IS_SHA256(flags))
+ if (IS_SHA256(flags))
cfg |= AUTH_MODE_HASH << AUTH_MODE_SHIFT;
- else if (IS_SHA1_HMAC(flags) || IS_SHA256_HMAC(flags))
+ else if (IS_SHA256_HMAC(flags))
cfg |= AUTH_MODE_HMAC << AUTH_MODE_SHIFT;
else if (IS_CCM(flags))
cfg |= AUTH_MODE_CCM << AUTH_MODE_SHIFT;
@@ -191,7 +188,7 @@ static int qce_setup_regs_ahash(struct crypto_async_request *async_req)
else
qce_cpu_to_be32p_array(auth, rctx->digest, digestsize);
- iv_words = (IS_SHA1(rctx->flags) || IS_SHA1_HMAC(rctx->flags)) ? 5 : 8;
+ iv_words = 8;
qce_write_array(qce, REG_AUTH_IV0, (u32 *)auth, iv_words);
if (rctx->first_blk)
@@ -243,19 +240,8 @@ static u32 qce_encr_cfg(unsigned long flags, u32 aes_key_size)
if (IS_AES(flags))
cfg |= ENCR_ALG_AES << ENCR_ALG_SHIFT;
- else if (IS_DES(flags) || IS_3DES(flags))
- cfg |= ENCR_ALG_DES << ENCR_ALG_SHIFT;
-
- if (IS_DES(flags))
- cfg |= ENCR_KEY_SZ_DES << ENCR_KEY_SZ_SHIFT;
-
- if (IS_3DES(flags))
- cfg |= ENCR_KEY_SZ_3DES << ENCR_KEY_SZ_SHIFT;
switch (flags & QCE_MODE_MASK) {
- case QCE_MODE_ECB:
- cfg |= ENCR_MODE_ECB << ENCR_MODE_SHIFT;
- break;
case QCE_MODE_CBC:
cfg |= ENCR_MODE_CBC << ENCR_MODE_SHIFT;
break;
@@ -340,13 +326,7 @@ static int qce_setup_regs_skcipher(struct crypto_async_request *async_req)
encr_cfg = qce_encr_cfg(flags, keylen);
- if (IS_DES(flags)) {
- enciv_words = 2;
- enckey_words = 2;
- } else if (IS_3DES(flags)) {
- enciv_words = 2;
- enckey_words = 6;
- } else if (IS_AES(flags)) {
+ if (IS_AES(flags)) {
if (IS_XTS(flags))
qce_xtskey(qce, ctx->enc_key, ctx->enc_keylen,
rctx->cryptlen);
@@ -357,14 +337,12 @@ static int qce_setup_regs_skcipher(struct crypto_async_request *async_req)
qce_write_array(qce, REG_ENCR_KEY0, (u32 *)enckey, enckey_words);
- if (!IS_ECB(flags)) {
- if (IS_XTS(flags))
- qce_xts_swapiv(enciv, rctx->iv, ivsize);
- else
- qce_cpu_to_be32p_array(enciv, rctx->iv, ivsize);
+ if (IS_XTS(flags))
+ qce_xts_swapiv(enciv, rctx->iv, ivsize);
+ else
+ qce_cpu_to_be32p_array(enciv, rctx->iv, ivsize);
- qce_write_array(qce, REG_CNTR0_IV0, (u32 *)enciv, enciv_words);
- }
+ qce_write_array(qce, REG_CNTR0_IV0, (u32 *)enciv, enciv_words);
if (IS_ENCRYPT(flags))
encr_cfg |= BIT(ENCODE_SHIFT);
@@ -393,10 +371,6 @@ static int qce_setup_regs_skcipher(struct crypto_async_request *async_req)
#endif
#ifdef CONFIG_CRYPTO_DEV_QCE_AEAD
-static const u32 std_iv_sha1[SHA256_DIGEST_SIZE / sizeof(u32)] = {
- SHA1_H0, SHA1_H1, SHA1_H2, SHA1_H3, SHA1_H4, 0, 0, 0
-};
-
static const u32 std_iv_sha256[SHA256_DIGEST_SIZE / sizeof(u32)] = {
SHA256_H0, SHA256_H1, SHA256_H2, SHA256_H3,
SHA256_H4, SHA256_H5, SHA256_H6, SHA256_H7
@@ -473,13 +447,8 @@ static int qce_setup_regs_aead(struct crypto_async_request *async_req)
/* Write initial authentication IV only for HMAC algorithms */
if (IS_SHA_HMAC(rctx->flags)) {
/* Write default authentication iv */
- if (IS_SHA1_HMAC(rctx->flags)) {
- auth_ivsize = SHA1_DIGEST_SIZE;
- memcpy(authiv, std_iv_sha1, auth_ivsize);
- } else if (IS_SHA256_HMAC(rctx->flags)) {
- auth_ivsize = SHA256_DIGEST_SIZE;
- memcpy(authiv, std_iv_sha256, auth_ivsize);
- }
+ auth_ivsize = SHA256_DIGEST_SIZE;
+ memcpy(authiv, std_iv_sha256, auth_ivsize);
authiv_words = auth_ivsize / sizeof(u32);
qce_write_array(qce, REG_AUTH_IV0, (u32 *)authiv, authiv_words);
} else if (IS_CCM(rctx->flags)) {
diff --git a/drivers/crypto/qce/common.h b/drivers/crypto/qce/common.h
index 02e63ad9f245..9cd2e6ed8bbb 100644
--- a/drivers/crypto/qce/common.h
+++ b/drivers/crypto/qce/common.h
@@ -22,7 +22,7 @@
/* IV length in bytes */
#define QCE_AES_IV_LENGTH AES_BLOCK_SIZE
-/* max of AES_BLOCK_SIZE, DES3_EDE_BLOCK_SIZE */
+/* max of AES_BLOCK_SIZE */
#define QCE_MAX_IV_SIZE AES_BLOCK_SIZE
/* maximum nonce bytes */
@@ -33,14 +33,10 @@
#define QCE_MAX_ALIGN_SIZE 64
/* cipher algorithms */
-#define QCE_ALG_DES BIT(0)
-#define QCE_ALG_3DES BIT(1)
#define QCE_ALG_AES BIT(2)
/* hash and hmac algorithms */
-#define QCE_HASH_SHA1 BIT(3)
#define QCE_HASH_SHA256 BIT(4)
-#define QCE_HASH_SHA1_HMAC BIT(5)
#define QCE_HASH_SHA256_HMAC BIT(6)
#define QCE_HASH_AES_CMAC BIT(7)
@@ -58,21 +54,15 @@
#define QCE_ENCRYPT BIT(30)
#define QCE_DECRYPT BIT(31)
-#define IS_DES(flags) (flags & QCE_ALG_DES)
-#define IS_3DES(flags) (flags & QCE_ALG_3DES)
#define IS_AES(flags) (flags & QCE_ALG_AES)
-#define IS_SHA1(flags) (flags & QCE_HASH_SHA1)
#define IS_SHA256(flags) (flags & QCE_HASH_SHA256)
-#define IS_SHA1_HMAC(flags) (flags & QCE_HASH_SHA1_HMAC)
#define IS_SHA256_HMAC(flags) (flags & QCE_HASH_SHA256_HMAC)
#define IS_CMAC(flags) (flags & QCE_HASH_AES_CMAC)
-#define IS_SHA(flags) (IS_SHA1(flags) || IS_SHA256(flags))
-#define IS_SHA_HMAC(flags) \
- (IS_SHA1_HMAC(flags) || IS_SHA256_HMAC(flags))
+#define IS_SHA(flags) IS_SHA256(flags)
+#define IS_SHA_HMAC(flags) IS_SHA256_HMAC(flags)
#define IS_CBC(mode) (mode & QCE_MODE_CBC)
-#define IS_ECB(mode) (mode & QCE_MODE_ECB)
#define IS_CTR(mode) (mode & QCE_MODE_CTR)
#define IS_XTS(mode) (mode & QCE_MODE_XTS)
#define IS_CCM(mode) (mode & QCE_MODE_CCM)
diff --git a/drivers/crypto/qce/core.c b/drivers/crypto/qce/core.c
index ea5b9689ce68..bf3c1bc3ba7b 100644
--- a/drivers/crypto/qce/core.c
+++ b/drivers/crypto/qce/core.c
@@ -11,6 +11,8 @@
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/pm_runtime.h>
#include <linux/types.h>
#include <crypto/algapi.h>
#include <crypto/internal/hash.h>
@@ -51,14 +53,14 @@ static void qce_unregister_algs(void *data)
static int devm_qce_register_algs(struct qce_device *qce)
{
const struct qce_algo_ops *ops;
- int i, j, ret = -ENODEV;
+ int i, ret;
for (i = 0; i < ARRAY_SIZE(qce_ops); i++) {
ops = qce_ops[i];
ret = ops->register_algs(qce);
if (ret) {
- for (j = i - 1; j >= 0; j--)
- qce_ops[j]->unregister_algs(qce);
+ while (i--)
+ qce_ops[i]->unregister_algs(qce);
return ret;
}
}
@@ -68,26 +70,29 @@ static int devm_qce_register_algs(struct qce_device *qce)
static int qce_handle_request(struct crypto_async_request *async_req)
{
- int ret = -EINVAL, i;
+ int i;
const struct qce_algo_ops *ops;
u32 type = crypto_tfm_alg_type(async_req->tfm);
for (i = 0; i < ARRAY_SIZE(qce_ops); i++) {
ops = qce_ops[i];
- if (type != ops->type)
- continue;
- ret = ops->async_req_handle(async_req);
- break;
+ if (type == ops->type)
+ return ops->async_req_handle(async_req);
}
- return ret;
+ return -EINVAL;
}
static int qce_handle_queue(struct qce_device *qce,
struct crypto_async_request *req)
{
struct crypto_async_request *async_req, *backlog;
- int ret = 0, err;
+ int ret, err;
+
+ PM_RUNTIME_ACQUIRE_AUTOSUSPEND(qce->dev, pm);
+ ret = PM_RUNTIME_ACQUIRE_ERR(&pm);
+ if (ret)
+ return ret;
scoped_guard(mutex, &qce->lock) {
if (req)
@@ -206,23 +211,33 @@ static int qce_crypto_probe(struct platform_device *pdev)
if (ret < 0)
return ret;
- qce->core = devm_clk_get_optional_enabled(qce->dev, "core");
+ qce->core = devm_clk_get_optional(qce->dev, "core");
if (IS_ERR(qce->core))
return PTR_ERR(qce->core);
- qce->iface = devm_clk_get_optional_enabled(qce->dev, "iface");
+ qce->iface = devm_clk_get_optional(qce->dev, "iface");
if (IS_ERR(qce->iface))
return PTR_ERR(qce->iface);
- qce->bus = devm_clk_get_optional_enabled(qce->dev, "bus");
+ qce->bus = devm_clk_get_optional(qce->dev, "bus");
if (IS_ERR(qce->bus))
return PTR_ERR(qce->bus);
- qce->mem_path = devm_of_icc_get(qce->dev, "memory");
+ qce->mem_path = devm_of_icc_get(dev, "memory");
if (IS_ERR(qce->mem_path))
return PTR_ERR(qce->mem_path);
- ret = icc_set_bw(qce->mem_path, QCE_DEFAULT_MEM_BANDWIDTH, QCE_DEFAULT_MEM_BANDWIDTH);
+ /*
+ * Enable runtime PM after clocks and ICC path are acquired so that
+ * the resume callback can enable clocks and apply the ICC bandwidth
+ * vote before any hardware access takes place.
+ */
+ ret = devm_pm_runtime_enable(dev);
+ if (ret)
+ return ret;
+
+ PM_RUNTIME_ACQUIRE_AUTOSUSPEND(dev, pm);
+ ret = PM_RUNTIME_ACQUIRE_ERR(&pm);
if (ret)
return ret;
@@ -244,9 +259,76 @@ static int qce_crypto_probe(struct platform_device *pdev)
qce->async_req_enqueue = qce_async_request_enqueue;
qce->async_req_done = qce_async_request_done;
- return devm_qce_register_algs(qce);
+ ret = devm_qce_register_algs(qce);
+ if (ret)
+ return ret;
+
+ /* Configure autosuspend after successful init */
+ pm_runtime_set_autosuspend_delay(dev, 100);
+ pm_runtime_use_autosuspend(dev);
+ pm_runtime_mark_last_busy(dev);
+
+ return 0;
+}
+
+static int qce_runtime_suspend(struct device *dev)
+{
+ struct qce_device *qce = dev_get_drvdata(dev);
+ int ret;
+
+ clk_disable_unprepare(qce->core);
+ clk_disable_unprepare(qce->iface);
+ clk_disable_unprepare(qce->bus);
+
+ ret = icc_set_bw(qce->mem_path, 0, 0);
+ if (ret) {
+ clk_prepare_enable(qce->bus);
+ clk_prepare_enable(qce->iface);
+ clk_prepare_enable(qce->core);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int qce_runtime_resume(struct device *dev)
+{
+ struct qce_device *qce = dev_get_drvdata(dev);
+ int ret;
+
+ ret = icc_set_bw(qce->mem_path, QCE_DEFAULT_MEM_BANDWIDTH,
+ QCE_DEFAULT_MEM_BANDWIDTH);
+ if (ret)
+ return ret;
+
+ ret = clk_prepare_enable(qce->core);
+ if (ret)
+ goto err_core;
+
+ ret = clk_prepare_enable(qce->iface);
+ if (ret)
+ goto err_iface;
+
+ ret = clk_prepare_enable(qce->bus);
+ if (ret)
+ goto err_bus;
+
+ return 0;
+
+err_bus:
+ clk_disable_unprepare(qce->iface);
+err_iface:
+ clk_disable_unprepare(qce->core);
+err_core:
+ icc_set_bw(qce->mem_path, 0, 0);
+ return ret;
}
+static const struct dev_pm_ops qce_crypto_pm_ops = {
+ RUNTIME_PM_OPS(qce_runtime_suspend, qce_runtime_resume, NULL)
+ SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
+};
+
static const struct of_device_id qce_crypto_of_match[] = {
{ .compatible = "qcom,crypto-v5.1", },
{ .compatible = "qcom,crypto-v5.4", },
@@ -260,6 +342,7 @@ static struct platform_driver qce_crypto_driver = {
.driver = {
.name = KBUILD_MODNAME,
.of_match_table = qce_crypto_of_match,
+ .pm = pm_ptr(&qce_crypto_pm_ops),
},
};
module_platform_driver(qce_crypto_driver);
diff --git a/drivers/crypto/qce/regs-v5.h b/drivers/crypto/qce/regs-v5.h
index d59ed2798906..431a7db1a4e7 100644
--- a/drivers/crypto/qce/regs-v5.h
+++ b/drivers/crypto/qce/regs-v5.h
@@ -203,7 +203,6 @@
#define AUTH_SIZE_SHIFT 9
#define AUTH_SIZE_MASK GENMASK(13, 9)
-#define AUTH_SIZE_SHA1 0
#define AUTH_SIZE_SHA256 1
#define AUTH_SIZE_ENUM_1_BYTES 0
#define AUTH_SIZE_ENUM_2_BYTES 1
@@ -284,15 +283,12 @@
#define ENCR_KEY_SZ_SHIFT 3
#define ENCR_KEY_SZ_MASK GENMASK(5, 3)
-#define ENCR_KEY_SZ_DES 0
-#define ENCR_KEY_SZ_3DES 1
#define ENCR_KEY_SZ_AES128 0
#define ENCR_KEY_SZ_AES256 2
#define ENCR_ALG_SHIFT 0
#define ENCR_ALG_MASK GENMASK(2, 0)
#define ENCR_ALG_NONE 0
-#define ENCR_ALG_DES 1
#define ENCR_ALG_AES 2
#define ENCR_ALG_KASUMI 4
#define ENCR_ALG_SNOW_3G 5
diff --git a/drivers/crypto/qce/sha.c b/drivers/crypto/qce/sha.c
index 1b37121cbcdc..eb8a5b0c4173 100644
--- a/drivers/crypto/qce/sha.c
+++ b/drivers/crypto/qce/sha.c
@@ -25,10 +25,6 @@ struct qce_sha_saved_state {
static LIST_HEAD(ahash_algs);
-static const u32 std_iv_sha1[SHA256_DIGEST_SIZE / sizeof(u32)] = {
- SHA1_H0, SHA1_H1, SHA1_H2, SHA1_H3, SHA1_H4, 0, 0, 0
-};
-
static const u32 std_iv_sha256[SHA256_DIGEST_SIZE / sizeof(u32)] = {
SHA256_H0, SHA256_H1, SHA256_H2, SHA256_H3,
SHA256_H4, SHA256_H5, SHA256_H6, SHA256_H7
@@ -187,10 +183,8 @@ static int qce_ahash_update(struct ahash_request *req)
struct qce_sha_reqctx *rctx = ahash_request_ctx_dma(req);
struct qce_alg_template *tmpl = to_ahash_tmpl(req->base.tfm);
struct qce_device *qce = tmpl->qce;
- struct scatterlist *sg_last, *sg;
- unsigned int total, len;
+ unsigned int total;
unsigned int hash_later;
- unsigned int nbytes;
unsigned int blocksize;
blocksize = crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
@@ -238,28 +232,8 @@ static int qce_ahash_update(struct ahash_request *req)
if (!hash_later)
hash_later = blocksize;
- if (hash_later) {
- unsigned int src_offset = req->nbytes - hash_later;
- scatterwalk_map_and_copy(rctx->buf, req->src, src_offset,
- hash_later, 0);
- }
-
- /* here nbytes is multiple of blocksize */
- nbytes = total - hash_later;
-
- len = rctx->buflen;
- sg = sg_last = req->src;
-
- while (len < nbytes && sg) {
- if (len + sg_dma_len(sg) > nbytes)
- break;
- len += sg_dma_len(sg);
- sg_last = sg;
- sg = sg_next(sg);
- }
-
- if (!sg_last)
- return -EINVAL;
+ scatterwalk_map_and_copy(rctx->buf, req->src, req->nbytes - hash_later,
+ hash_later, 0);
if (rctx->buflen) {
sg_init_table(rctx->sg, 2);
@@ -268,7 +242,8 @@ static int qce_ahash_update(struct ahash_request *req)
req->src = rctx->sg;
}
- req->nbytes = nbytes;
+ /* hash only complete blocks */
+ req->nbytes = total - hash_later;
rctx->buflen = hash_later;
return qce->async_req_enqueue(tmpl->qce, &req->base);
@@ -349,9 +324,7 @@ static int qce_ahash_hmac_setkey(struct crypto_ahash *tfm, const u8 *key,
return 0;
}
- if (digestsize == SHA1_DIGEST_SIZE)
- alg_name = "sha1-qce";
- else if (digestsize == SHA256_DIGEST_SIZE)
+ if (digestsize == SHA256_DIGEST_SIZE)
alg_name = "sha256-qce";
else
return -EINVAL;
@@ -413,15 +386,6 @@ struct qce_ahash_def {
static const struct qce_ahash_def ahash_def[] = {
{
- .flags = QCE_HASH_SHA1,
- .name = "sha1",
- .drv_name = "sha1-qce",
- .digestsize = SHA1_DIGEST_SIZE,
- .blocksize = SHA1_BLOCK_SIZE,
- .statesize = sizeof(struct qce_sha_saved_state),
- .std_iv = std_iv_sha1,
- },
- {
.flags = QCE_HASH_SHA256,
.name = "sha256",
.drv_name = "sha256-qce",
@@ -431,15 +395,6 @@ static const struct qce_ahash_def ahash_def[] = {
.std_iv = std_iv_sha256,
},
{
- .flags = QCE_HASH_SHA1_HMAC,
- .name = "hmac(sha1)",
- .drv_name = "hmac-sha1-qce",
- .digestsize = SHA1_DIGEST_SIZE,
- .blocksize = SHA1_BLOCK_SIZE,
- .statesize = sizeof(struct qce_sha_saved_state),
- .std_iv = std_iv_sha1,
- },
- {
.flags = QCE_HASH_SHA256_HMAC,
.name = "hmac(sha256)",
.drv_name = "hmac-sha256-qce",
@@ -476,9 +431,7 @@ static int qce_ahash_register_one(const struct qce_ahash_def *def,
alg->halg.digestsize = def->digestsize;
alg->halg.statesize = def->statesize;
- if (IS_SHA1(def->flags))
- tmpl->hash_zero = sha1_zero_message_hash;
- else if (IS_SHA256(def->flags))
+ if (IS_SHA256(def->flags))
tmpl->hash_zero = sha256_zero_message_hash;
base = &alg->halg.base;
diff --git a/drivers/crypto/qce/sha.h b/drivers/crypto/qce/sha.h
index a22695361f16..cb822fc334dc 100644
--- a/drivers/crypto/qce/sha.h
+++ b/drivers/crypto/qce/sha.h
@@ -7,7 +7,6 @@
#define _SHA_H_
#include <crypto/scatterwalk.h>
-#include <crypto/sha1.h>
#include <crypto/sha2.h>
#include "common.h"
diff --git a/drivers/crypto/qce/skcipher.c b/drivers/crypto/qce/skcipher.c
index db0b648a56eb..4931b064f10e 100644
--- a/drivers/crypto/qce/skcipher.c
+++ b/drivers/crypto/qce/skcipher.c
@@ -11,7 +11,6 @@
#include <linux/types.h>
#include <linux/errno.h>
#include <crypto/aes.h>
-#include <crypto/internal/des.h>
#include <crypto/internal/skcipher.h>
#include "cipher.h"
@@ -209,51 +208,6 @@ static int qce_skcipher_setkey(struct crypto_skcipher *ablk, const u8 *key,
return ret;
}
-static int qce_des_setkey(struct crypto_skcipher *ablk, const u8 *key,
- unsigned int keylen)
-{
- struct qce_cipher_ctx *ctx = crypto_skcipher_ctx(ablk);
- int err;
-
- err = verify_skcipher_des_key(ablk, key);
- if (err)
- return err;
-
- ctx->enc_keylen = keylen;
- memcpy(ctx->enc_key, key, keylen);
- return 0;
-}
-
-static int qce_des3_setkey(struct crypto_skcipher *ablk, const u8 *key,
- unsigned int keylen)
-{
- struct qce_cipher_ctx *ctx = crypto_skcipher_ctx(ablk);
- u32 _key[6];
- int err;
-
- err = verify_skcipher_des3_key(ablk, key);
- if (err)
- return err;
-
- /*
- * The crypto engine does not support any two keys
- * being the same for triple des algorithms. The
- * verify_skcipher_des3_key does not check for all the
- * below conditions. Return -ENOKEY in case any two keys
- * are the same. Revisit to see if a fallback cipher
- * is needed to handle this condition.
- */
- memcpy(_key, key, DES3_EDE_KEY_SIZE);
- if (!((_key[0] ^ _key[2]) | (_key[1] ^ _key[3])) ||
- !((_key[2] ^ _key[4]) | (_key[3] ^ _key[5])) ||
- !((_key[0] ^ _key[4]) | (_key[1] ^ _key[5])))
- return -ENOKEY;
-
- ctx->enc_keylen = keylen;
- memcpy(ctx->enc_key, key, keylen);
- return 0;
-}
-
static int qce_skcipher_crypt(struct skcipher_request *req, int encrypt)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
@@ -262,7 +216,6 @@ static int qce_skcipher_crypt(struct skcipher_request *req, int encrypt)
struct qce_alg_template *tmpl = to_cipher_tmpl(tfm);
unsigned int blocksize = crypto_skcipher_blocksize(tfm);
int keylen;
- int ret;
rctx->flags = tmpl->alg_flags;
rctx->flags |= encrypt ? QCE_ENCRYPT : QCE_DECRYPT;
@@ -276,7 +229,7 @@ static int qce_skcipher_crypt(struct skcipher_request *req, int encrypt)
* ECB and CBC algorithms require message lengths to be
* multiples of block size.
*/
- if (IS_ECB(rctx->flags) || IS_CBC(rctx->flags))
+ if (IS_CBC(rctx->flags))
if (!IS_ALIGNED(req->cryptlen, blocksize))
return -EINVAL;
@@ -300,9 +253,8 @@ static int qce_skcipher_crypt(struct skcipher_request *req, int encrypt)
req->base.data);
skcipher_request_set_crypt(&rctx->fallback_req, req->src,
req->dst, req->cryptlen, req->iv);
- ret = encrypt ? crypto_skcipher_encrypt(&rctx->fallback_req) :
- crypto_skcipher_decrypt(&rctx->fallback_req);
- return ret;
+ return encrypt ? crypto_skcipher_encrypt(&rctx->fallback_req) :
+ crypto_skcipher_decrypt(&rctx->fallback_req);
}
return tmpl->qce->async_req_enqueue(tmpl->qce, &req->base);
@@ -360,15 +312,6 @@ struct qce_skcipher_def {
static const struct qce_skcipher_def skcipher_def[] = {
{
- .flags = QCE_ALG_AES | QCE_MODE_ECB,
- .name = "ecb(aes)",
- .drv_name = "ecb-aes-qce",
- .blocksize = AES_BLOCK_SIZE,
- .ivsize = 0,
- .min_keysize = AES_MIN_KEY_SIZE,
- .max_keysize = AES_MAX_KEY_SIZE,
- },
- {
.flags = QCE_ALG_AES | QCE_MODE_CBC,
.name = "cbc(aes)",
.drv_name = "cbc-aes-qce",
@@ -396,42 +339,6 @@ static const struct qce_skcipher_def skcipher_def[] = {
.min_keysize = AES_MIN_KEY_SIZE * 2,
.max_keysize = AES_MAX_KEY_SIZE * 2,
},
- {
- .flags = QCE_ALG_DES | QCE_MODE_ECB,
- .name = "ecb(des)",
- .drv_name = "ecb-des-qce",
- .blocksize = DES_BLOCK_SIZE,
- .ivsize = 0,
- .min_keysize = DES_KEY_SIZE,
- .max_keysize = DES_KEY_SIZE,
- },
- {
- .flags = QCE_ALG_DES | QCE_MODE_CBC,
- .name = "cbc(des)",
- .drv_name = "cbc-des-qce",
- .blocksize = DES_BLOCK_SIZE,
- .ivsize = DES_BLOCK_SIZE,
- .min_keysize = DES_KEY_SIZE,
- .max_keysize = DES_KEY_SIZE,
- },
- {
- .flags = QCE_ALG_3DES | QCE_MODE_ECB,
- .name = "ecb(des3_ede)",
- .drv_name = "ecb-3des-qce",
- .blocksize = DES3_EDE_BLOCK_SIZE,
- .ivsize = 0,
- .min_keysize = DES3_EDE_KEY_SIZE,
- .max_keysize = DES3_EDE_KEY_SIZE,
- },
- {
- .flags = QCE_ALG_3DES | QCE_MODE_CBC,
- .name = "cbc(des3_ede)",
- .drv_name = "cbc-3des-qce",
- .blocksize = DES3_EDE_BLOCK_SIZE,
- .ivsize = DES3_EDE_BLOCK_SIZE,
- .min_keysize = DES3_EDE_KEY_SIZE,
- .max_keysize = DES3_EDE_KEY_SIZE,
- },
};
static int qce_skcipher_register_one(const struct qce_skcipher_def *def,
@@ -455,9 +362,7 @@ static int qce_skcipher_register_one(const struct qce_skcipher_def *def,
alg->ivsize = def->ivsize;
alg->min_keysize = def->min_keysize;
alg->max_keysize = def->max_keysize;
- alg->setkey = IS_3DES(def->flags) ? qce_des3_setkey :
- IS_DES(def->flags) ? qce_des_setkey :
- qce_skcipher_setkey;
+ alg->setkey = qce_skcipher_setkey;
alg->encrypt = qce_skcipher_encrypt;
alg->decrypt = qce_skcipher_decrypt;
diff --git a/drivers/crypto/rockchip/rk3288_crypto.c b/drivers/crypto/rockchip/rk3288_crypto.c
index b77bdce8e7fc..7cb1316b6f18 100644
--- a/drivers/crypto/rockchip/rk3288_crypto.c
+++ b/drivers/crypto/rockchip/rk3288_crypto.c
@@ -365,10 +365,8 @@ static int rk_crypto_probe(struct platform_device *pdev)
rk_crypto_irq_handle, IRQF_SHARED,
"rk-crypto", pdev);
- if (err) {
- dev_err(&pdev->dev, "irq request failed.\n");
+ if (err)
goto err_crypto;
- }
crypto_info->engine = crypto_engine_alloc_init(&pdev->dev, true);
if (!crypto_info->engine) {
diff --git a/drivers/crypto/rockchip/rk3288_crypto_ahash.c b/drivers/crypto/rockchip/rk3288_crypto_ahash.c
index b9f5a8b42e66..d3482619aa2f 100644
--- a/drivers/crypto/rockchip/rk3288_crypto_ahash.c
+++ b/drivers/crypto/rockchip/rk3288_crypto_ahash.c
@@ -324,7 +324,12 @@ static int rk_hash_run(struct crypto_engine *engine, void *breq)
* efficiency, and make it response quickly when dma
* complete.
*/
- readl_poll_timeout(rkc->reg + RK_CRYPTO_HASH_STS, v, v == 0, 10, 1000);
+ err = readl_poll_timeout(rkc->reg + RK_CRYPTO_HASH_STS, v,
+ v == 0, 10, 1000);
+ if (err) {
+ dev_err(rkc->dev, "HASH idle timeout\n");
+ goto theend;
+ }
for (i = 0; i < crypto_ahash_digestsize(tfm) / 4; i++) {
v = readl(rkc->reg + RK_CRYPTO_HASH_DOUT_0 + i * 4);
diff --git a/drivers/crypto/sa2ul.c b/drivers/crypto/sa2ul.c
index 965a03d5b27a..9846cbeb3449 100644
--- a/drivers/crypto/sa2ul.c
+++ b/drivers/crypto/sa2ul.c
@@ -22,6 +22,7 @@
#include <crypto/aes.h>
#include <crypto/authenc.h>
+#include <crypto/utils.h>
#include <crypto/des.h>
#include <crypto/internal/aead.h>
#include <crypto/internal/hash.h>
@@ -1688,7 +1689,7 @@ static void sa_aead_dma_in_callback(void *data)
scatterwalk_map_and_copy(auth_tag, req->src, start, authsize,
0);
- err = memcmp(&mdptr[4], auth_tag, authsize) ? -EBADMSG : 0;
+ err = crypto_memneq(&mdptr[4], auth_tag, authsize) ? -EBADMSG : 0;
}
sa_free_sa_rx_data(rxd);
@@ -2395,7 +2396,10 @@ static int sa_ul_probe(struct platform_device *pdev)
return ret;
}
- sa_init_mem(dev_data);
+ ret = sa_init_mem(dev_data);
+ if (ret)
+ goto disable_pm;
+
ret = sa_dma_init(dev_data);
if (ret)
goto destroy_dma_pool;
@@ -2430,6 +2434,7 @@ release_dma:
destroy_dma_pool:
dma_pool_destroy(dev_data->sc_pool);
+disable_pm:
pm_runtime_put_sync(dev);
pm_runtime_disable(dev);
diff --git a/drivers/crypto/sahara.c b/drivers/crypto/sahara.c
index 533080b0cddc..d586f1315de1 100644
--- a/drivers/crypto/sahara.c
+++ b/drivers/crypto/sahara.c
@@ -1305,8 +1305,7 @@ static int sahara_probe(struct platform_device *pdev)
err = devm_request_irq(&pdev->dev, irq, sahara_irq_handler,
0, dev_name(&pdev->dev), dev);
if (err)
- return dev_err_probe(&pdev->dev, err,
- "failed to request irq\n");
+ return err;
/* clocks */
dev->clk_ipg = devm_clk_get_enabled(&pdev->dev, "ipg");
diff --git a/drivers/crypto/stm32/stm32-cryp.c b/drivers/crypto/stm32/stm32-cryp.c
index b79877099942..3fc2db290b0f 100644
--- a/drivers/crypto/stm32/stm32-cryp.c
+++ b/drivers/crypto/stm32/stm32-cryp.c
@@ -2590,10 +2590,8 @@ static int stm32_cryp_probe(struct platform_device *pdev)
ret = devm_request_threaded_irq(dev, irq, stm32_cryp_irq,
stm32_cryp_irq_thread, IRQF_ONESHOT,
dev_name(dev), cryp);
- if (ret) {
- dev_err(dev, "Cannot grab IRQ\n");
+ if (ret)
return ret;
- }
cryp->clk = devm_clk_get(dev, NULL);
if (IS_ERR(cryp->clk)) {
diff --git a/drivers/crypto/stm32/stm32-hash.c b/drivers/crypto/stm32/stm32-hash.c
index dada5951082c..e6a1e9b9f88d 100644
--- a/drivers/crypto/stm32/stm32-hash.c
+++ b/drivers/crypto/stm32/stm32-hash.c
@@ -2356,10 +2356,8 @@ static int stm32_hash_probe(struct platform_device *pdev)
stm32_hash_irq_thread,
IRQF_ONESHOT,
dev_name(dev), hdev);
- if (ret) {
- dev_err(dev, "Cannot grab IRQ\n");
+ if (ret)
return ret;
- }
} else {
dev_info(dev, "No IRQ, use polling mode\n");
hdev->polled = true;
diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 3a3fd21d2c4d..fa96b6bf17e3 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -191,7 +191,7 @@ static int reset_device(struct device *dev)
&& --timeout)
cpu_relax();
- if (priv->irq[1]) {
+ if (priv->irq[1] > 0) {
mcr = TALITOS_MCR_RCA1 | TALITOS_MCR_RCA3;
setbits32(priv->reg + TALITOS_MCR, mcr);
}
@@ -3241,13 +3241,11 @@ static void talitos_remove(struct platform_device *ofdev)
talitos_unregister_rng(dev);
for (i = 0; i < 2; i++)
- if (priv->irq[i]) {
+ if (priv->irq[i] > 0)
free_irq(priv->irq[i], dev);
- irq_dispose_mapping(priv->irq[i]);
- }
tasklet_kill(&priv->done_task[0]);
- if (priv->irq[1])
+ if (priv->irq[1] > 0)
tasklet_kill(&priv->done_task[1]);
}
@@ -3353,26 +3351,26 @@ static struct talitos_crypto_alg *talitos_alg_alloc(struct device *dev,
static int talitos_probe_irq(struct platform_device *ofdev)
{
struct device *dev = &ofdev->dev;
- struct device_node *np = ofdev->dev.of_node;
struct talitos_private *priv = dev_get_drvdata(dev);
int err;
bool is_sec1 = has_ftr_sec1(priv);
- priv->irq[0] = irq_of_parse_and_map(np, 0);
- if (!priv->irq[0]) {
- dev_err(dev, "failed to map irq\n");
- return -EINVAL;
- }
+ 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);
goto primary_out;
}
- priv->irq[1] = irq_of_parse_and_map(np, 1);
+ priv->irq[1] = platform_get_irq_optional(ofdev, 1);
+ if (priv->irq[1] == -EPROBE_DEFER)
+ return priv->irq[1];
/* get the primary irq line */
- if (!priv->irq[1]) {
+ if (priv->irq[1] < 0) {
err = request_irq(priv->irq[0], talitos2_interrupt_4ch, 0,
dev_driver_string(dev), dev);
goto primary_out;
@@ -3388,7 +3386,6 @@ static int talitos_probe_irq(struct platform_device *ofdev)
dev_driver_string(dev), dev);
if (err) {
dev_err(dev, "failed to request secondary irq\n");
- irq_dispose_mapping(priv->irq[1]);
priv->irq[1] = 0;
}
@@ -3397,7 +3394,6 @@ static int talitos_probe_irq(struct platform_device *ofdev)
primary_out:
if (err) {
dev_err(dev, "failed to request primary irq\n");
- irq_dispose_mapping(priv->irq[0]);
priv->irq[0] = 0;
}
@@ -3498,7 +3494,7 @@ static int talitos_probe(struct platform_device *ofdev)
tasklet_init(&priv->done_task[0], talitos1_done_4ch,
(unsigned long)dev);
} else {
- if (priv->irq[1]) {
+ if (priv->irq[1] > 0) {
tasklet_init(&priv->done_task[0], talitos2_done_ch0_2,
(unsigned long)dev);
tasklet_init(&priv->done_task[1], talitos2_done_ch1_3,
@@ -3516,7 +3512,7 @@ static int talitos_probe(struct platform_device *ofdev)
for (i = 0; i < priv->num_channels; i++) {
priv->chan[i].reg = priv->reg + stride * (i + 1);
- if (!priv->irq[1] || !(i & 1))
+ if (priv->irq[1] < 0 || !(i & 1))
priv->chan[i].reg += TALITOS_CH_BASE_OFFSET;
spin_lock_init(&priv->chan[i].head_lock);
diff --git a/drivers/gpu/drm/ci/arm64.config b/drivers/gpu/drm/ci/arm64.config
index 563a69669a7b..c46125c1f80f 100644
--- a/drivers/gpu/drm/ci/arm64.config
+++ b/drivers/gpu/drm/ci/arm64.config
@@ -78,7 +78,6 @@ CONFIG_INTERCONNECT_QCOM_MSM8996=y
CONFIG_INTERCONNECT_QCOM_OSM_L3=y
CONFIG_INTERCONNECT_QCOM_SC7180=y
CONFIG_INTERCONNECT_QCOM_SM8350=y
-CONFIG_CRYPTO_DEV_QCOM_RNG=y
CONFIG_SC_DISPCC_7180=y
CONFIG_SC_GPUCC_7180=y
CONFIG_SM_GPUCC_8350=y
@@ -189,6 +188,7 @@ CONFIG_GNSS=y
CONFIG_GNSS_MTK_SERIAL=y
CONFIG_HW_RANDOM=y
CONFIG_HW_RANDOM_MTK=y
+CONFIG_HW_RANDOM_QCOM=y
CONFIG_MTK_DEVAPC=y
CONFIG_PWM_MTK_DISP=y
CONFIG_MTK_CMDQ=y
diff --git a/include/crypto/aes.h b/include/crypto/aes.h
index 16fbfd93e2bd..3279cfa54608 100644
--- a/include/crypto/aes.h
+++ b/include/crypto/aes.h
@@ -259,7 +259,7 @@ int aes_p8_set_decrypt_key(const u8 *userKey, const int bits,
void aes_p8_encrypt(const u8 *in, u8 *out, const struct p8_aes_key *key);
void aes_p8_decrypt(const u8 *in, u8 *out, const struct p8_aes_key *key);
void aes_p8_cbc_encrypt(const u8 *in, u8 *out, size_t len,
- const struct p8_aes_key *key, u8 *iv, const int enc);
+ const struct p8_aes_key *key, u8 *iv, bool enc);
void aes_p8_ctr32_encrypt_blocks(const u8 *in, u8 *out, size_t len,
const struct p8_aes_key *key, const u8 *iv);
void aes_p8_xts_encrypt(const u8 *in, u8 *out, size_t len,
diff --git a/include/crypto/if_alg.h b/include/crypto/if_alg.h
index 7643ba954125..0d51428c1da4 100644
--- a/include/crypto/if_alg.h
+++ b/include/crypto/if_alg.h
@@ -8,6 +8,7 @@
#ifndef _CRYPTO_IF_ALG_H
#define _CRYPTO_IF_ALG_H
+#include <linux/bits.h>
#include <linux/compiler.h>
#include <linux/completion.h>
#include <linux/if_alg.h>
@@ -121,7 +122,7 @@ struct af_alg_async_req {
* @iv: IV for cipher operation
* @state: Existing state for continuing operation
* @aead_assoclen: Length of AAD for AEAD cipher operations
- * @completion: Work queue for synchronous operation
+ * @wait: For waiting for completion of async crypto ops
* @used: TX bytes sent to kernel. This variable is used to
* ensure that user space cannot cause the kernel
* to allocate too much memory in sendmsg operation.
@@ -161,9 +162,20 @@ struct af_alg_ctx {
unsigned int inflight;
};
+/* Flags for af_alg_allowlist_entry::flags: */
+#define AF_ALG_UNPRIVILEGED BIT(0) /* Unprivileged use is allowed */
+
+struct af_alg_allowlist_entry {
+ const char *name;
+ u32 flags;
+};
+
int af_alg_register_type(const struct af_alg_type *type);
int af_alg_unregister_type(const struct af_alg_type *type);
+int af_alg_check_restriction(const char *name,
+ const struct af_alg_allowlist_entry allowlist[]);
+
int af_alg_release(struct socket *sock);
void af_alg_release_parent(struct sock *sk);
int af_alg_accept(struct sock *sk, struct socket *newsock,
@@ -177,10 +189,11 @@ static inline struct alg_sock *alg_sk(struct sock *sk)
}
/**
- * Size of available buffer for sending data from user space to kernel.
+ * af_alg_sndbuf - Size of available buffer for sending data from user space to kernel.
*
- * @sk socket of connection to user space
- * @return number of bytes still available
+ * @sk: socket of connection to user space
+ *
+ * Returns: number of bytes still available
*/
static inline int af_alg_sndbuf(struct sock *sk)
{
@@ -192,10 +205,11 @@ static inline int af_alg_sndbuf(struct sock *sk)
}
/**
- * Can the send buffer still be written to?
+ * af_alg_writable - Can the send buffer still be written to?
+ *
+ * @sk: socket of connection to user space
*
- * @sk socket of connection to user space
- * @return true => writable, false => not writable
+ * Returns: true => writable, false => not writable
*/
static inline bool af_alg_writable(struct sock *sk)
{
@@ -203,10 +217,11 @@ static inline bool af_alg_writable(struct sock *sk)
}
/**
- * Size of available buffer used by kernel for the RX user space operation.
+ * af_alg_rcvbuf - Size of available buffer used by kernel for the RX user space operation.
*
- * @sk socket of connection to user space
- * @return number of bytes still available
+ * @sk: socket of connection to user space
+ *
+ * Returns: number of bytes still available
*/
static inline int af_alg_rcvbuf(struct sock *sk)
{
@@ -218,10 +233,11 @@ static inline int af_alg_rcvbuf(struct sock *sk)
}
/**
- * Can the RX buffer still be written to?
+ * af_alg_readable - Can the RX buffer still be read from?
+ *
+ * @sk: socket of connection to user space
*
- * @sk socket of connection to user space
- * @return true => writable, false => not writable
+ * Returns: true => readable, false => not readable
*/
static inline bool af_alg_readable(struct sock *sk)
{
diff --git a/include/crypto/internal/ecc.h b/include/crypto/internal/ecc.h
index a4b48d76f53a..d67fe13a543a 100644
--- a/include/crypto/internal/ecc.h
+++ b/include/crypto/internal/ecc.h
@@ -149,7 +149,7 @@ int crypto_ecdh_shared_secret(unsigned int curve_id, unsigned int ndigits,
* @curve: elliptic curve domain parameters
* @pk: public key as a point
*
- * Valdiate public key according to SP800-56A section 5.6.2.3.4 ECC Partial
+ * Validate public key according to SP800-56A section 5.6.2.3.4 ECC Partial
* Public-Key Validation Routine.
*
* Note: There is no check that the public key is in the correct elliptic curve
@@ -166,7 +166,7 @@ int ecc_is_pubkey_valid_partial(const struct ecc_curve *curve,
* @curve: elliptic curve domain parameters
* @pk: public key as a point
*
- * Valdiate public key according to SP800-56A section 5.6.2.3.3 ECC Full
+ * Validate public key according to SP800-56A section 5.6.2.3.3 ECC Full
* Public-Key Validation Routine.
*
* Return: 0 if validation is successful, -EINVAL if validation is failed.
diff --git a/include/linux/psp-sev.h b/include/linux/psp-sev.h
index ce16bbc0b308..03a79786df1d 100644
--- a/include/linux/psp-sev.h
+++ b/include/linux/psp-sev.h
@@ -129,6 +129,7 @@ enum sev_cmd {
SEV_CMD_SNP_LAUNCH_FINISH = 0x0A2,
SEV_CMD_SNP_DBG_DECRYPT = 0x0B0,
SEV_CMD_SNP_DBG_ENCRYPT = 0x0B1,
+ SEV_CMD_SNP_VERIFY_MITIGATION = 0x0B2,
SEV_CMD_SNP_PAGE_SWAP_OUT = 0x0C0,
SEV_CMD_SNP_PAGE_SWAP_IN = 0x0C1,
SEV_CMD_SNP_PAGE_MOVE = 0x0C2,
@@ -898,10 +899,60 @@ struct snp_feature_info {
#define SNP_CIPHER_TEXT_HIDING_SUPPORTED BIT(3)
#define SNP_AES_256_XTS_POLICY_SUPPORTED BIT(4)
#define SNP_CXL_ALLOW_POLICY_SUPPORTED BIT(5)
+#define SNP_VERIFY_MITIGATION_SUPPORTED BIT(13)
/* Feature bits in EBX */
#define SNP_SEV_TIO_SUPPORTED BIT(1)
+#define SNP_MIT_SUBCMD_REQ_STATUS 0x0
+#define SNP_MIT_SUBCMD_REQ_VERIFY 0x1
+
+/**
+ * struct sev_data_snp_verify_mitigation - SNP_VERIFY_MITIGATION command params
+ *
+ * @length: Length of the command buffer read by the PSP
+ * @subcommand: Mitigation sub-command for the firmware to execute.
+ * REQ_STATUS: 0x0 - Request status about currently supported and
+ * verified mitigations
+ * REQ_VERIFY: 0x1 - Request to initiate verification mitigation
+ * operation on a specific mitigation
+ * @rsvd: Reserved
+ * @vector: Bit specifying the vulnerability mitigation to process
+ * @dst_paddr_en: Destination paddr enabled
+ * @src_paddr_en: Source paddr enabled
+ * @rsvd1: Reserved
+ * @rsvd2: Reserved
+ * @src_paddr: Source address for optional input data
+ * @dst_paddr: Destination address to write the result
+ * @rsvd3: Reserved
+ */
+struct sev_data_snp_verify_mitigation {
+ u32 length;
+ u16 subcommand;
+ u16 rsvd;
+ u64 vector;
+ u32 dst_paddr_en : 1,
+ src_paddr_en : 1,
+ rsvd1 : 30;
+ u8 rsvd2[4];
+ u64 src_paddr;
+ u64 dst_paddr;
+ u8 rsvd3[24];
+} __packed;
+
+/**
+ * struct sev_data_snp_verify_mitigation_dst - mitigation result vectors
+ *
+ * @mit_verified_vector: Bit vector of vulnerability mitigations verified
+ * @mit_supported_vector: Bit vector of vulnerability mitigations supported
+ * @mit_failure_status: Status of the verification operation
+ */
+struct sev_data_snp_verify_mitigation_dst {
+ u64 mit_verified_vector; /* OUT */
+ u64 mit_supported_vector; /* OUT */
+ u32 mit_failure_status; /* OUT */
+} __packed;
+
/**
* struct sev_snp_tcb_version_genoa_milan
*
diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h
index 79f83b6eec27..57a2a29bef0e 100644
--- a/include/linux/rhashtable.h
+++ b/include/linux/rhashtable.h
@@ -23,7 +23,6 @@
#include <linux/irq_work.h>
#include <linux/jhash.h>
#include <linux/list_nulls.h>
-#include <linux/workqueue.h>
#include <linux/rculist.h>
#include <linux/bit_spinlock.h>
diff --git a/include/uapi/linux/psp-sfs.h b/include/uapi/linux/psp-sfs.h
index 94e51670383c..fe9402c8a575 100644
--- a/include/uapi/linux/psp-sfs.h
+++ b/include/uapi/linux/psp-sfs.h
@@ -12,7 +12,7 @@
#include <linux/types.h>
-/**
+/*
* SFS: AMD Seamless Firmware Support (SFS) interface
*/
@@ -43,7 +43,7 @@ struct sfs_user_update_package {
__u32 sfs_extended_status;
} __packed;
-/**
+/*
* Seamless Firmware Support (SFS) IOC
*
* possible return codes for all SFS IOCTLs:
diff --git a/lib/rhashtable.c b/lib/rhashtable.c
index 8b2c405e7a66..6362896e4f09 100644
--- a/lib/rhashtable.c
+++ b/lib/rhashtable.c
@@ -14,6 +14,7 @@
#include <linux/atomic.h>
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/irq_work.h>
#include <linux/log2.h>
#include <linux/sched.h>
#include <linux/rculist.h>
@@ -25,6 +26,7 @@
#include <linux/rhashtable.h>
#include <linux/err.h>
#include <linux/export.h>
+#include <linux/workqueue.h>
#define HASH_DEFAULT_SIZE 64UL
#define HASH_MIN_SIZE 4U