diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-08-19 17:25:42 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-08-19 17:25:42 -0700 |
| commit | a4ff2be345d0abc943da8dd8da98151843b750dc (patch) | |
| tree | da64a462ec69df460299cfec5e0d61534daa8c7c | |
| parent | a51ec5e8e5dae80824239f0344210060cb92a4b0 (diff) | |
| parent | 7537036a2e6fe96f8ed82034f755c54714a0e417 (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
...
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, ¶ms) < 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 |
