* [PATCH 1/7] crypto: qcom-rng - Enable clock in hwrng case
2026-06-15 22:41 [PATCH 0/7] Finish removing crypto_rng from drivers/crypto/ Eric Biggers
@ 2026-06-15 22:41 ` Eric Biggers
2026-06-15 22:41 ` [PATCH 2/7] crypto: qcom-rng - Allow zero as a random number Eric Biggers
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Eric Biggers @ 2026-06-15 22:41 UTC (permalink / raw)
To: linux-crypto, Herbert Xu
Cc: linux-kernel, Gaurav Jain, Horia Geantă, Pankaj Gupta,
Corentin Labbe, Dmitry Baryshkov, Konrad Dybcio, linux-arm-msm,
Eric Biggers, stable
Fix qcom-rng.c to enable the clock before accessing the hardware.
Fixes: f29cd5bb64c2 ("crypto: qcom-rng - Add hw_random interface support")
Cc: stable@vger.kernel.org
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
---
drivers/crypto/qcom-rng.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/drivers/crypto/qcom-rng.c b/drivers/crypto/qcom-rng.c
index 150e5802e351..f31a7fe07ba7 100644
--- a/drivers/crypto/qcom-rng.c
+++ b/drivers/crypto/qcom-rng.c
@@ -111,17 +111,31 @@ static int qcom_rng_seed(struct crypto_rng *tfm, const u8 *seed,
unsigned int slen)
{
return 0;
}
+static int qcom_hwrng_init(struct hwrng *hwrng)
+{
+ struct qcom_rng *qrng = container_of(hwrng, struct qcom_rng, hwrng);
+
+ return clk_prepare_enable(qrng->clk);
+}
+
static int qcom_hwrng_read(struct hwrng *hwrng, void *data, size_t max, bool wait)
{
struct qcom_rng *qrng = container_of(hwrng, struct qcom_rng, hwrng);
return qcom_rng_read(qrng, data, max);
}
+static void qcom_hwrng_cleanup(struct hwrng *hwrng)
+{
+ struct qcom_rng *qrng = container_of(hwrng, struct qcom_rng, hwrng);
+
+ clk_disable_unprepare(qrng->clk);
+}
+
static int qcom_rng_enable(struct qcom_rng *rng)
{
u32 val;
int ret;
@@ -206,11 +220,13 @@ static int qcom_rng_probe(struct platform_device *pdev)
return ret;
}
if (rng->match_data->hwrng_support) {
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);
qcom_rng_dev = NULL;
--
2.54.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH 2/7] crypto: qcom-rng - Allow zero as a random number
2026-06-15 22:41 [PATCH 0/7] Finish removing crypto_rng from drivers/crypto/ Eric Biggers
2026-06-15 22:41 ` [PATCH 1/7] crypto: qcom-rng - Enable clock in hwrng case Eric Biggers
@ 2026-06-15 22:41 ` Eric Biggers
2026-06-15 22:41 ` [PATCH 3/7] crypto: qcom-rng - Remove crypto_rng interface Eric Biggers
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Eric Biggers @ 2026-06-15 22:41 UTC (permalink / raw)
To: linux-crypto, Herbert Xu
Cc: linux-kernel, Gaurav Jain, Horia Geantă, Pankaj Gupta,
Corentin Labbe, Dmitry Baryshkov, Konrad Dybcio, linux-arm-msm,
Eric Biggers, stable
Zero is a valid random number and needs to be allowed. Otherwise the
output is distinguishable from random.
Fixes: f29cd5bb64c2 ("crypto: qcom-rng - Add hw_random interface support")
Cc: stable@vger.kernel.org
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
---
drivers/crypto/qcom-rng.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/drivers/crypto/qcom-rng.c b/drivers/crypto/qcom-rng.c
index f31a7fe07ba7..7058bd98f9e9 100644
--- a/drivers/crypto/qcom-rng.c
+++ b/drivers/crypto/qcom-rng.c
@@ -63,12 +63,10 @@ static int qcom_rng_read(struct qcom_rng *rng, u8 *data, unsigned int max)
200, 10000);
if (ret)
return ret;
val = readl_relaxed(rng->base + PRNG_DATA_OUT);
- if (!val)
- return -EINVAL;
if ((max - currsize) >= WORD_SZ) {
memcpy(data, &val, WORD_SZ);
data += WORD_SZ;
currsize += WORD_SZ;
--
2.54.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH 3/7] crypto: qcom-rng - Remove crypto_rng interface
2026-06-15 22:41 [PATCH 0/7] Finish removing crypto_rng from drivers/crypto/ Eric Biggers
2026-06-15 22:41 ` [PATCH 1/7] crypto: qcom-rng - Enable clock in hwrng case Eric Biggers
2026-06-15 22:41 ` [PATCH 2/7] crypto: qcom-rng - Allow zero as a random number Eric Biggers
@ 2026-06-15 22:41 ` Eric Biggers
2026-06-15 22:41 ` [PATCH 4/7] hwrng: qcom - Move qcom-rng.c into drivers/char/hw_random/ Eric Biggers
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Eric Biggers @ 2026-06-15 22:41 UTC (permalink / raw)
To: linux-crypto, Herbert Xu
Cc: linux-kernel, Gaurav Jain, Horia Geantă, Pankaj Gupta,
Corentin Labbe, Dmitry Baryshkov, Konrad Dybcio, linux-arm-msm,
Eric Biggers, stable
qcom-rng.c exposes the same hardware through two completely separate
interfaces, crypto_rng and hwrng. However, the implementation of this
is buggy because it permits generation operations from these interfaces
to run concurrently with each other, accessing the same registers. That
is, qcom_rng_generate() synchronizes with itself but not with
qcom_hwrng_read(). This results in potential repetition of output from
the RNG, output of non-random values, etc.
Fortunately, there's actually no point in hardware RNG drivers
implementing the crypto_rng interface. It's not actually used by
anything besides the "rng" algorithm type of AF_ALG, which in turn is
not actually used in practice. Other crypto_rng hardware drivers are
likewise being phased out, leaving just the hwrng support.
Thus, remove it to simplify the code and avoid conflict (and confusion)
with the hwrng interface which is the one that actually matters.
Fixes: f29cd5bb64c2 ("crypto: qcom-rng - Add hw_random interface support")
Cc: stable@vger.kernel.org
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
---
drivers/crypto/Kconfig | 1 -
drivers/crypto/qcom-rng.c | 158 +++++---------------------------------
2 files changed, 19 insertions(+), 140 deletions(-)
diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index 216a00bad5d7..eb834d15d614 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -639,11 +639,10 @@ config CRYPTO_DEV_QCE_SW_MAX_LEN
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
diff --git a/drivers/crypto/qcom-rng.c b/drivers/crypto/qcom-rng.c
index 7058bd98f9e9..4d046caafe5b 100644
--- a/drivers/crypto/qcom-rng.c
+++ b/drivers/crypto/qcom-rng.c
@@ -1,14 +1,12 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2017-18 Linaro Limited
//
// 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>
#include <linux/kernel.h>
#include <linux/module.h>
@@ -30,28 +28,19 @@
#define WORD_SZ 4
#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;
u32 val;
int ret;
@@ -78,41 +67,10 @@ static int qcom_rng_read(struct qcom_rng *rng, u8 *data, unsigned int max)
} while (currsize < max);
return currsize;
}
-static int qcom_rng_generate(struct crypto_rng *tfm,
- const u8 *src, unsigned int slen,
- u8 *dstn, unsigned int dlen)
-{
- 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;
-}
-
-static int qcom_rng_seed(struct crypto_rng *tfm, const u8 *seed,
- unsigned int slen)
-{
- return 0;
-}
-
static int qcom_hwrng_init(struct hwrng *hwrng)
{
struct qcom_rng *qrng = container_of(hwrng, struct qcom_rng, hwrng);
return clk_prepare_enable(qrng->clk);
@@ -130,135 +88,58 @@ static void qcom_hwrng_cleanup(struct hwrng *hwrng)
struct qcom_rng *qrng = container_of(hwrng, struct qcom_rng, hwrng);
clk_disable_unprepare(qrng->clk);
}
-static int qcom_rng_enable(struct qcom_rng *rng)
-{
- 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);
-
- return 0;
-}
-
-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);
rng->clk = devm_clk_get_optional(&pdev->dev, "core");
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.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);
- 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,
};
static const struct acpi_device_id __maybe_unused qcom_rng_acpi_match[] = {
{ .id = "QCOM8160", .driver_data = (kernel_ulong_t)&qcom_prng_ee_match_data },
@@ -274,11 +155,10 @@ static const struct of_device_id __maybe_unused qcom_rng_of_match[] = {
};
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,
.acpi_match_table = ACPI_PTR(qcom_rng_acpi_match),
}
--
2.54.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH 4/7] hwrng: qcom - Move qcom-rng.c into drivers/char/hw_random/
2026-06-15 22:41 [PATCH 0/7] Finish removing crypto_rng from drivers/crypto/ Eric Biggers
` (2 preceding siblings ...)
2026-06-15 22:41 ` [PATCH 3/7] crypto: qcom-rng - Remove crypto_rng interface Eric Biggers
@ 2026-06-15 22:41 ` Eric Biggers
2026-06-15 22:41 ` [PATCH 5/7] crypto: sun8i-ce - Remove crypto_rng interface Eric Biggers
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Eric Biggers @ 2026-06-15 22:41 UTC (permalink / raw)
To: linux-crypto, Herbert Xu
Cc: linux-kernel, Gaurav Jain, Horia Geantă, Pankaj Gupta,
Corentin Labbe, Dmitry Baryshkov, Konrad Dybcio, linux-arm-msm,
Eric Biggers
Since this file just implements a hwrng driver, move it into
drivers/char/hw_random/. Rename the kconfig option accordingly as well.
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
---
arch/arm/configs/multi_v7_defconfig | 2 +-
arch/arm/configs/qcom_defconfig | 2 +-
arch/arm64/configs/defconfig | 2 +-
drivers/char/hw_random/Kconfig | 11 +++++++++++
drivers/char/hw_random/Makefile | 1 +
drivers/{crypto => char/hw_random}/qcom-rng.c | 0
drivers/crypto/Kconfig | 11 -----------
drivers/crypto/Makefile | 1 -
drivers/gpu/drm/ci/arm64.config | 2 +-
9 files changed, 16 insertions(+), 16 deletions(-)
rename drivers/{crypto => char/hw_random}/qcom-rng.c (100%)
diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index 3672dd12df60..8e1f70339a47 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -404,10 +404,11 @@ CONFIG_SERIAL_DEV_BUS=y
CONFIG_VIRTIO_CONSOLE=y
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
CONFIG_I2C_ARB_GPIO_CHALLENGE=m
CONFIG_I2C_MUX_GPIO=y
@@ -1333,11 +1334,10 @@ CONFIG_CRYPTO_DEV_S5P=m
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
CONFIG_CMA_SIZE_MBYTES=64
CONFIG_PRINTK_TIME=y
diff --git a/arch/arm/configs/qcom_defconfig b/arch/arm/configs/qcom_defconfig
index 29a1dea500f0..d57554971c03 100644
--- a/arch/arm/configs/qcom_defconfig
+++ b/arch/arm/configs/qcom_defconfig
@@ -115,10 +115,11 @@ CONFIG_SERIO_LIBPS2=y
# CONFIG_LEGACY_PTYS is not set
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
CONFIG_SPI=y
CONFIG_SPI_QUP=y
@@ -309,11 +310,10 @@ CONFIG_CRYPTO_USER=m
CONFIG_CRYPTO_USER_API=m
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
CONFIG_DYNAMIC_DEBUG=y
CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 6745189b1fbc..7958932a5b2a 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -550,10 +550,11 @@ CONFIG_IPMI_DEVICE_INTERFACE=m
CONFIG_IPMI_SI=m
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
CONFIG_TCG_TIS_SPI_CR50=y
CONFIG_TCG_TIS_I2C_CR50=m
@@ -1953,11 +1954,10 @@ CONFIG_CRYPTO_AES_ARM64_BS=m
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
CONFIG_CRYPTO_DEV_CCREE=m
CONFIG_CRYPTO_DEV_HISI_SEC2=m
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
index a5bcef4a54ee..b4c359abc4f9 100644
--- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -634,10 +634,21 @@ config HW_RANDOM_XILINX
Generator and Pseudo random Number in CTR_DRBG mode as defined in NIST SP800-90A.
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
depends on UML
select HW_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
@@ -52,5 +52,6 @@ obj-$(CONFIG_HW_RANDOM_ARM_SMCCC_TRNG) += arm_smccc_trng.o
obj-$(CONFIG_HW_RANDOM_CN10K) += cn10k-rng.o
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/crypto/qcom-rng.c b/drivers/char/hw_random/qcom-rng.c
similarity index 100%
rename from drivers/crypto/qcom-rng.c
rename to drivers/char/hw_random/qcom-rng.c
diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index eb834d15d614..03a8f7a1f75e 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -635,21 +635,10 @@ config CRYPTO_DEV_QCE_SW_MAX_LEN
Note that 192-bit keys are not supported by the hardware and are
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
- 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
select CRYPTO_MD5
select CRYPTO_SHA1
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index 5a950c7abc39..2c33b83f3cfa 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -25,11 +25,10 @@ obj-$(CONFIG_CRYPTO_DEV_OMAP_DES) += omap-des.o
obj-$(CONFIG_CRYPTO_DEV_OMAP_SHAM) += omap-sham.o
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
obj-$(CONFIG_CRYPTO_DEV_SAHARA) += sahara.o
obj-$(CONFIG_CRYPTO_DEV_SL3516) += gemini/
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
@@ -76,11 +76,10 @@ CONFIG_INTERCONNECT_QCOM_SDM845=y
CONFIG_INTERCONNECT_QCOM_MSM8916=y
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
CONFIG_QCOM_SPMI_ADC5=y
CONFIG_QCOM_SPMI_VADC=y
@@ -187,10 +186,11 @@ CONFIG_PWM_MEDIATEK=y
CONFIG_DRM_MEDIATEK_HDMI=y
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
CONFIG_REGULATOR_DA9211=y
CONFIG_DRM_ANALOGIX_ANX7625=y
--
2.54.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH 5/7] crypto: sun8i-ce - Remove crypto_rng interface
2026-06-15 22:41 [PATCH 0/7] Finish removing crypto_rng from drivers/crypto/ Eric Biggers
` (3 preceding siblings ...)
2026-06-15 22:41 ` [PATCH 4/7] hwrng: qcom - Move qcom-rng.c into drivers/char/hw_random/ Eric Biggers
@ 2026-06-15 22:41 ` Eric Biggers
2026-06-15 22:41 ` [PATCH 6/7] crypto: sun8i-ss " Eric Biggers
2026-06-15 22:41 ` [PATCH 7/7] crypto: caam " Eric Biggers
6 siblings, 0 replies; 8+ messages in thread
From: Eric Biggers @ 2026-06-15 22:41 UTC (permalink / raw)
To: linux-crypto, Herbert Xu
Cc: linux-kernel, Gaurav Jain, Horia Geantă, Pankaj Gupta,
Corentin Labbe, Dmitry Baryshkov, Konrad Dybcio, linux-arm-msm,
Eric Biggers, stable
Since the crypto_rng interface for hardware PRNGs is unused and is
redundant with hwrng and the actual Linux RNG, it's being phased out.
Most drivers for it were already removed. Go ahead and remove the
sun8i-ce support which is one of the only remaining ones.
Note that the sun8i-ce support for hwrng remains in place. That is the
interface that actually matters.
As usual for crypto_rng, this driver was also buggy: its ->generate()
function had a use-after-free vulnerability due to using
wait_for_completion_interruptible_timeout() without handling shutting
down the DMA operation if a signal is sent. There's no point in fixing
this separately only to remove the code anyway, so this commit is marked
with Fixes and Cc stable.
Fixes: 5eb7e9468884 ("crypto: sun8i-ce - Add support for the PRNG")
Cc: stable@vger.kernel.org
Cc: Corentin Labbe <clabbe.montjoie@gmail.com>
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
---
drivers/crypto/allwinner/Kconfig | 8 -
drivers/crypto/allwinner/sun8i-ce/Makefile | 1 -
.../crypto/allwinner/sun8i-ce/sun8i-ce-core.c | 63 -------
.../crypto/allwinner/sun8i-ce/sun8i-ce-prng.c | 159 ------------------
drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h | 29 ----
5 files changed, 260 deletions(-)
delete mode 100644 drivers/crypto/allwinner/sun8i-ce/sun8i-ce-prng.c
diff --git a/drivers/crypto/allwinner/Kconfig b/drivers/crypto/allwinner/Kconfig
index 06ea0e9fe6f2..17bf9ead6ef2 100644
--- a/drivers/crypto/allwinner/Kconfig
+++ b/drivers/crypto/allwinner/Kconfig
@@ -68,18 +68,10 @@ config CRYPTO_DEV_SUN8I_CE_HASH
select CRYPTO_SHA256
select CRYPTO_SHA512
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
select HW_RANDOM
help
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..c6402e87f8a0 100644
--- a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c
+++ b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c
@@ -10,11 +10,10 @@
* You could find a link for the datasheet in Documentation/arch/arm/sunxi.rst
*/
#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>
#include <linux/dma-mapping.h>
#include <linux/err.h>
@@ -47,11 +46,10 @@ static const struct ce_variant ce_h3_variant = {
.ce_clks = {
{ "bus", 0, 200000000 },
{ "mod", 50000000, 0 },
},
.esr = ESR_H3,
- .prng = CE_ALG_PRNG,
.trng = CE_ID_NOTSUPP,
};
static const struct ce_variant ce_h5_variant = {
.alg_cipher = { CE_ALG_AES, CE_ALG_DES, CE_ALG_3DES,
@@ -64,11 +62,10 @@ static const struct ce_variant ce_h5_variant = {
.ce_clks = {
{ "bus", 0, 200000000 },
{ "mod", 300000000, 0 },
},
.esr = ESR_H5,
- .prng = CE_ALG_PRNG,
.trng = CE_ID_NOTSUPP,
};
static const struct ce_variant ce_h6_variant = {
.alg_cipher = { CE_ALG_AES, CE_ALG_DES, CE_ALG_3DES,
@@ -78,19 +75,17 @@ static const struct ce_variant ce_h6_variant = {
},
.op_mode = { CE_OP_ECB, CE_OP_CBC
},
.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 },
{ "mod", 300000000, 0 },
{ "ram", 0, 400000000 },
},
.esr = ESR_H6,
- .prng = CE_ALG_PRNG_V2,
.trng = CE_ALG_TRNG_V2,
};
static const struct ce_variant ce_h616_variant = {
.alg_cipher = { CE_ALG_AES, CE_ALG_DES, CE_ALG_3DES,
@@ -100,21 +95,19 @@ static const struct ce_variant ce_h616_variant = {
},
.op_mode = { CE_OP_ECB, CE_OP_CBC
},
.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 = {
{ "bus", 0, 200000000 },
{ "mod", 300000000, 0 },
{ "ram", 0, 400000000 },
{ "trng", 0, 0 },
},
.esr = ESR_H6,
- .prng = CE_ALG_PRNG_V2,
.trng = CE_ALG_TRNG_V2,
};
static const struct ce_variant ce_a64_variant = {
.alg_cipher = { CE_ALG_AES, CE_ALG_DES, CE_ALG_3DES,
@@ -127,11 +120,10 @@ static const struct ce_variant ce_a64_variant = {
.ce_clks = {
{ "bus", 0, 200000000 },
{ "mod", 300000000, 0 },
},
.esr = ESR_A64,
- .prng = CE_ALG_PRNG,
.trng = CE_ID_NOTSUPP,
};
static const struct ce_variant ce_d1_variant = {
.alg_cipher = { CE_ALG_AES, CE_ALG_DES, CE_ALG_3DES,
@@ -146,11 +138,10 @@ static const struct ce_variant ce_d1_variant = {
{ "mod", 300000000, 0 },
{ "ram", 0, 400000000 },
{ "trng", 0, 0 },
},
.esr = ESR_D1,
- .prng = CE_ALG_PRNG,
.trng = CE_ALG_TRNG,
};
static const struct ce_variant ce_r40_variant = {
.alg_cipher = { CE_ALG_AES, CE_ALG_DES, CE_ALG_3DES,
@@ -163,11 +154,10 @@ static const struct ce_variant ce_r40_variant = {
.ce_clks = {
{ "bus", 0, 200000000 },
{ "mod", 300000000, 0 },
},
.esr = ESR_R40,
- .prng = CE_ALG_PRNG,
.trng = CE_ID_NOTSUPP,
};
static void sun8i_ce_dump_task_descriptors(struct sun8i_ce_flow *chan)
{
@@ -612,29 +602,10 @@ static struct sun8i_ce_alg_template ce_algs[] = {
.alg.hash.op = {
.do_one_request = sun8i_ce_hash_run,
},
},
#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)
{
struct sun8i_ce_dev *ce __maybe_unused = seq->private;
@@ -691,18 +662,10 @@ static int sun8i_ce_debugfs_show(struct seq_file *seq, void *v)
seq_printf(seq, "\tFallback due to alignment: %lu\n",
ce_algs[i].stat_fb_srcali);
seq_printf(seq, "\tFallback due to SG numbers: %lu\n",
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) && \
defined(CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG)
@@ -928,29 +891,10 @@ static int sun8i_ce_register_algs(struct sun8i_ce_dev *ce)
ce_algs[i].alg.hash.base.halg.base.cra_name);
ce_algs[i].ce = NULL;
return err;
}
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");
}
@@ -975,17 +919,10 @@ static void sun8i_ce_unregister_algs(struct sun8i_ce_dev *ce)
case CRYPTO_ALG_TYPE_AHASH:
dev_info(ce->dev, "Unregister %d %s\n", i,
ce_algs[i].alg.hash.base.halg.base.cra_name);
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
}
}
}
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
@@ -13,11 +13,10 @@
#include <linux/debugfs.h>
#include <linux/crypto.h>
#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>
/* CE Registers */
#define CE_TDQ 0x00
@@ -56,13 +55,11 @@
#define CE_ALG_SHA224 18
#define CE_ALG_SHA256 19
#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
#define CE_ID_CIPHER_AES 0
@@ -94,14 +91,10 @@
#define ESR_R40 2
#define ESR_H5 3
#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
#define MAX_SG 8
@@ -134,31 +127,26 @@ struct ce_clock {
* @op_mode: list of supported block modes
* @cipher_t_dlen_in_bytes: Does the request size for cipher is in
* 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 {
char alg_cipher[CE_ID_CIPHER_MAX];
char alg_hash[CE_ID_HASH_MAX];
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;
};
struct sginfo {
__le32 addr;
@@ -325,20 +313,10 @@ struct sun8i_ce_hash_reqctx {
u8 result[CE_MAX_HASH_DIGEST_SIZE] __aligned(CRYPTO_DMA_ALIGN);
u8 pad[2 * CE_MAX_HASH_BLOCK_SIZE];
struct ahash_request fallback_req; // keep at the end
};
-/*
- * 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
* @ce_blockmode: the type of block operation CE_ID
@@ -355,11 +333,10 @@ struct sun8i_ce_alg_template {
u32 ce_blockmode;
struct sun8i_ce_dev *ce;
union {
struct skcipher_engine_alg skcipher;
struct ahash_engine_alg hash;
- struct rng_alg rng;
} alg;
unsigned long stat_req;
unsigned long stat_fb;
unsigned long stat_bytes;
unsigned long stat_fb_maxsg;
@@ -396,13 +373,7 @@ int sun8i_ce_hash_final(struct ahash_request *areq);
int sun8i_ce_hash_update(struct ahash_request *areq);
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);
--
2.54.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH 6/7] crypto: sun8i-ss - Remove crypto_rng interface
2026-06-15 22:41 [PATCH 0/7] Finish removing crypto_rng from drivers/crypto/ Eric Biggers
` (4 preceding siblings ...)
2026-06-15 22:41 ` [PATCH 5/7] crypto: sun8i-ce - Remove crypto_rng interface Eric Biggers
@ 2026-06-15 22:41 ` Eric Biggers
2026-06-15 22:41 ` [PATCH 7/7] crypto: caam " Eric Biggers
6 siblings, 0 replies; 8+ messages in thread
From: Eric Biggers @ 2026-06-15 22:41 UTC (permalink / raw)
To: linux-crypto, Herbert Xu
Cc: linux-kernel, Gaurav Jain, Horia Geantă, Pankaj Gupta,
Corentin Labbe, Dmitry Baryshkov, Konrad Dybcio, linux-arm-msm,
Eric Biggers, stable
Since the crypto_rng interface for hardware PRNGs is unused and is
redundant with hwrng and the actual Linux RNG, it's being phased out.
Most drivers for it were already removed. Go ahead and remove the
sun8i-ss support which is one of the only remaining ones.
As usual for crypto_rng, this driver was also buggy: its ->generate()
function had a use-after-free vulnerability due to using
wait_for_completion_interruptible_timeout() without handling shutting
down the DMA operation if a signal is sent. Also, it had a buffer
overread bug in the line 'memcpy(ctx->seed, d + dlen, ctx->slen);'.
There's no point in fixing these bugs separately only to remove the code
anyway, so this commit is marked with Fixes and Cc stable.
Fixes: ac2614d721de ("crypto: sun8i-ss - Add support for the PRNG")
Cc: stable@vger.kernel.org
Cc: Corentin Labbe <clabbe.montjoie@gmail.com>
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
---
drivers/crypto/allwinner/Kconfig | 8 -
drivers/crypto/allwinner/sun8i-ss/Makefile | 1 -
.../crypto/allwinner/sun8i-ss/sun8i-ss-core.c | 45 -----
.../crypto/allwinner/sun8i-ss/sun8i-ss-prng.c | 177 ------------------
drivers/crypto/allwinner/sun8i-ss/sun8i-ss.h | 23 ---
5 files changed, 254 deletions(-)
delete mode 100644 drivers/crypto/allwinner/sun8i-ss/sun8i-ss-prng.c
diff --git a/drivers/crypto/allwinner/Kconfig b/drivers/crypto/allwinner/Kconfig
index 17bf9ead6ef2..d86ae005fbe2 100644
--- a/drivers/crypto/allwinner/Kconfig
+++ b/drivers/crypto/allwinner/Kconfig
@@ -103,18 +103,10 @@ config CRYPTO_DEV_SUN8I_SS_DEBUG
help
Say y to enable sun8i-ss debug stats.
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
select CRYPTO_MD5
select CRYPTO_SHA1
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..0b22fcddb882 100644
--- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c
+++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c
@@ -9,11 +9,10 @@
*
* You could find a link for the datasheet in Documentation/arch/arm/sunxi.rst
*/
#include <crypto/engine.h>
-#include <crypto/internal/rng.h>
#include <crypto/internal/skcipher.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/err.h>
@@ -281,29 +280,10 @@ static struct sun8i_ss_alg_template ss_algs[] = {
},
.alg.skcipher.op = {
.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,
.alg.hash.base = {
.init = sun8i_ss_hash_init,
@@ -499,18 +479,10 @@ static int sun8i_ss_debugfs_show(struct seq_file *seq, void *v)
seq_printf(seq, "\tFallback due to alignment: %lu\n",
ss_algs[i].stat_fb_align);
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",
ss_algs[i].alg.hash.base.halg.base.cra_driver_name,
ss_algs[i].alg.hash.base.halg.base.cra_name,
@@ -709,20 +681,10 @@ static int sun8i_ss_register_algs(struct sun8i_ss_dev *ss)
ss_algs[i].alg.skcipher.base.base.cra_name);
ss_algs[i].ss = NULL;
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;
ss_method = ss->variant->alg_hash[id];
if (ss_method == SS_ID_NOTSUPP) {
@@ -762,17 +724,10 @@ static void sun8i_ss_unregister_algs(struct sun8i_ss_dev *ss)
case CRYPTO_ALG_TYPE_SKCIPHER:
dev_info(ss->dev, "Unregister %d %s\n", i,
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,
ss_algs[i].alg.hash.base.halg.base.cra_name);
crypto_engine_unregister_ahash(&ss_algs[i].alg.hash);
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
@@ -6,11 +6,10 @@
* Copyright (C) 2016-2019 Corentin LABBE <clabbe.montjoie@gmail.com>
*/
#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>
#include <linux/crypto.h>
#include <crypto/internal/hash.h>
@@ -25,11 +24,10 @@
#define SS_ALG_AES 0
#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)
#define SS_CTL_REG 0x00
@@ -66,24 +64,19 @@
#define SS_ID_HASH_MAX 4
#define SS_FLOW0 BIT(30)
#define SS_FLOW1 BIT(31)
-#define SS_PRNG_CONTINUE BIT(18)
-
#define MAX_SG 8
#define MAXFLOW 2
#define SS_MAX_CLOCKS 2
#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
/*
* struct ss_clock - Describe clocks used by sun8i-ss
* @name: Name of clock needed by this variant
@@ -211,20 +204,10 @@ struct sun8i_cipher_tfm_ctx {
u32 keylen;
struct sun8i_ss_dev *ss;
struct crypto_skcipher *fallback_tfm;
};
-/*
- * 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
*/
@@ -272,11 +255,10 @@ struct sun8i_ss_alg_template {
u32 ss_algo_id;
u32 ss_blockmode;
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;
unsigned long stat_fb;
unsigned long stat_bytes;
@@ -298,15 +280,10 @@ int sun8i_ss_skdecrypt(struct skcipher_request *areq);
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);
int sun8i_ss_hash_init(struct ahash_request *areq);
int sun8i_ss_hash_export(struct ahash_request *areq, void *out);
--
2.54.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH 7/7] crypto: caam - Remove crypto_rng interface
2026-06-15 22:41 [PATCH 0/7] Finish removing crypto_rng from drivers/crypto/ Eric Biggers
` (5 preceding siblings ...)
2026-06-15 22:41 ` [PATCH 6/7] crypto: sun8i-ss " Eric Biggers
@ 2026-06-15 22:41 ` Eric Biggers
6 siblings, 0 replies; 8+ messages in thread
From: Eric Biggers @ 2026-06-15 22:41 UTC (permalink / raw)
To: linux-crypto, Herbert Xu
Cc: linux-kernel, Gaurav Jain, Horia Geantă, Pankaj Gupta,
Corentin Labbe, Dmitry Baryshkov, Konrad Dybcio, linux-arm-msm,
Eric Biggers
Since the crypto_rng interface for hardware PRNGs is unused and is
redundant with hwrng and the actual Linux RNG, it's being phased out.
Most drivers for it were already removed. Go ahead and remove the CAAM
support which is one of the only remaining ones.
Note that the CAAM support for hwrng remains in place. That is the
interface that actually matters.
Note that this code also had several issues, including dlen > 65535
causing corruption of the CAAM descriptor.
Cc: Gaurav Jain <gaurav.jain@nxp.com>
Cc: Horia Geantă <horia.geanta@nxp.com>
Cc: Pankaj Gupta <pankaj.gupta@nxp.com>
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
---
drivers/crypto/caam/Kconfig | 9 --
drivers/crypto/caam/Makefile | 1 -
drivers/crypto/caam/caamprng.c | 241 ---------------------------------
drivers/crypto/caam/intern.h | 15 --
drivers/crypto/caam/jr.c | 2 -
5 files changed, 268 deletions(-)
delete mode 100644 drivers/crypto/caam/caamprng.c
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
@@ -143,24 +143,15 @@ config CRYPTO_DEV_FSL_CAAM_PKC_API
signature and verification.
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
config CRYPTO_DEV_FSL_CAAM_RNG_TEST
bool "Test caam rng"
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
@@ -18,11 +18,10 @@ caam-y := ctrl.o
caam_jr-y := jr.o key_gen.o
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
caam-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI) += qi.o
caam-$(CONFIG_DEBUG_FS) += debugfs.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
@@ -210,25 +210,10 @@ static inline int caam_rng_init(struct device *dev)
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);
void caam_qi_algapi_exit(void);
diff --git a/drivers/crypto/caam/jr.c b/drivers/crypto/caam/jr.c
index 0ef00df9730e..bddeaaaca487 100644
--- a/drivers/crypto/caam/jr.c
+++ b/drivers/crypto/caam/jr.c
@@ -38,11 +38,10 @@ static void register_algs(struct caam_drv_private_jr *jrpriv,
caam_algapi_init(dev);
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:
mutex_unlock(&algs_lock);
}
@@ -53,11 +52,10 @@ static void unregister_algs(void)
if (--active_devs != 0)
goto algs_unlock;
caam_qi_algapi_exit();
- caam_prng_unregister(NULL);
caam_pkc_exit();
caam_algapi_hash_exit();
caam_algapi_exit();
algs_unlock:
--
2.54.0
^ permalink raw reply related [flat|nested] 8+ messages in thread