* [PATCH v3 0/3] Add Versal TRNG driver
@ 2025-06-12 5:25 Harsh Jain
2025-06-12 5:25 ` [PATCH v3 1/3] dt-bindings: crypto: Add node for True Random Number Generator Harsh Jain
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Harsh Jain @ 2025-06-12 5:25 UTC (permalink / raw)
To: herbert, davem, linux-crypto, devicetree, mounika.botcha,
sarat.chand.savitala, mohan.dhanawade, michal.simek
Cc: Harsh Jain
Versal TRNG module consist of array of Ring Oscillators as entropy source
and a deterministic CTR_DRBG random bit generator (DRBG). Add driver to
registers entropy source to hwrng and CTR_DRBG generator to crypto subsystem.
Derivation Function (DF) defined in NIST SP-800-90A for CTR_DRBG is not
supported in current TRNG IP. For DF processing, Update drbg module to
export CTR_DRBG derivation function.
Changes in v3
- Fix yaml warning introduced in v2.
- Squash fix patches
Changes in v2
- Fixed signoff chain
- Added 3 patch to fix Kernel test robot bugs
Harsh Jain (2):
crypto: xilinx: Add TRNG driver for Versal
crypto: drbg: Export CTR DRBG DF functions
Mounika Botcha (1):
dt-bindings: crypto: Add node for True Random Number Generator
.../bindings/crypto/xlnx,versal-trng.yaml | 36 ++
MAINTAINERS | 6 +
crypto/drbg.c | 108 +++--
drivers/crypto/Kconfig | 14 +
drivers/crypto/xilinx/Makefile | 1 +
drivers/crypto/xilinx/xilinx-trng.c | 434 ++++++++++++++++++
include/crypto/drbg.h | 15 +
7 files changed, 563 insertions(+), 51 deletions(-)
create mode 100644 Documentation/devicetree/bindings/crypto/xlnx,versal-trng.yaml
create mode 100644 drivers/crypto/xilinx/xilinx-trng.c
--
2.34.1
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v3 1/3] dt-bindings: crypto: Add node for True Random Number Generator
2025-06-12 5:25 [PATCH v3 0/3] Add Versal TRNG driver Harsh Jain
@ 2025-06-12 5:25 ` Harsh Jain
2025-06-17 7:11 ` Krzysztof Kozlowski
2025-06-12 5:25 ` [PATCH v3 2/3] crypto: xilinx: Add TRNG driver for Versal Harsh Jain
2025-06-12 5:25 ` [PATCH v3 3/3] crypto: drbg: Export CTR DRBG DF functions Harsh Jain
2 siblings, 1 reply; 8+ messages in thread
From: Harsh Jain @ 2025-06-12 5:25 UTC (permalink / raw)
To: herbert, davem, linux-crypto, devicetree, mounika.botcha,
sarat.chand.savitala, mohan.dhanawade, michal.simek
Cc: Harsh Jain
From: Mounika Botcha <mounika.botcha@amd.com>
Add TRNG node compatible string and reg properities.
Signed-off-by: Mounika Botcha <mounika.botcha@amd.com>
Signed-off-by: Harsh Jain <h.jain@amd.com>
---
.../bindings/crypto/xlnx,versal-trng.yaml | 36 +++++++++++++++++++
1 file changed, 36 insertions(+)
create mode 100644 Documentation/devicetree/bindings/crypto/xlnx,versal-trng.yaml
diff --git a/Documentation/devicetree/bindings/crypto/xlnx,versal-trng.yaml b/Documentation/devicetree/bindings/crypto/xlnx,versal-trng.yaml
new file mode 100644
index 000000000000..180adb96e5e7
--- /dev/null
+++ b/Documentation/devicetree/bindings/crypto/xlnx,versal-trng.yaml
@@ -0,0 +1,36 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/crypto/xlnx,versal-trng.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Xilinx Versal True Random Number Generator Hardware Accelerator
+
+maintainers:
+ - Harsh Jain <h.jain@amd.com>
+ - Mounika Botcha <mounika.botcha@amd.com>
+
+description:
+ The Versal True Random Number Generator consists of Ring Oscillators as
+ entropy source and a deterministic CTR_DRBG random bit generator (DRBG).
+
+properties:
+ compatible:
+ const: xlnx,versal-trng
+
+ reg:
+ maxItems: 1
+
+required:
+ - reg
+
+additionalProperties: false
+
+examples:
+ - |
+ rng@f1230000 {
+ compatible = "xlnx,versal-trng";
+ reg = <0xf1230000 0x1000>;
+ };
+...
+
--
2.34.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v3 2/3] crypto: xilinx: Add TRNG driver for Versal
2025-06-12 5:25 [PATCH v3 0/3] Add Versal TRNG driver Harsh Jain
2025-06-12 5:25 ` [PATCH v3 1/3] dt-bindings: crypto: Add node for True Random Number Generator Harsh Jain
@ 2025-06-12 5:25 ` Harsh Jain
2025-06-12 5:25 ` [PATCH v3 3/3] crypto: drbg: Export CTR DRBG DF functions Harsh Jain
2 siblings, 0 replies; 8+ messages in thread
From: Harsh Jain @ 2025-06-12 5:25 UTC (permalink / raw)
To: herbert, davem, linux-crypto, devicetree, mounika.botcha,
sarat.chand.savitala, mohan.dhanawade, michal.simek
Cc: Harsh Jain
Add True Random Number Generator(TRNG) driver for Versal
platform.
Co-developed-by: Mounika Botcha <mounika.botcha@amd.com>
Signed-off-by: Mounika Botcha <mounika.botcha@amd.com>
Signed-off-by: Harsh Jain <h.jain@amd.com>
---
MAINTAINERS | 6 +
drivers/crypto/Kconfig | 12 +
drivers/crypto/xilinx/Makefile | 1 +
drivers/crypto/xilinx/xilinx-trng.c | 408 ++++++++++++++++++++++++++++
4 files changed, 427 insertions(+)
create mode 100644 drivers/crypto/xilinx/xilinx-trng.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 85f7619e06b6..6995a0017a35 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -26578,6 +26578,12 @@ F: drivers/misc/Makefile
F: drivers/misc/xilinx_sdfec.c
F: include/uapi/misc/xilinx_sdfec.h
+XILINX TRNG DRIVER
+M: Mounika Botcha <mounika.botcha@amd.com>
+M: Harsh Jain <h.jain@amd.com>
+S: Maintained
+F: drivers/crypto/xilinx/xilinx-trng.c
+
XILINX UARTLITE SERIAL DRIVER
M: Peter Korsgaard <jacmet@sunsite.dk>
L: linux-serial@vger.kernel.org
diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index 5686369779be..209720b42ec6 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -711,6 +711,18 @@ config CRYPTO_DEV_TEGRA
Select this to enable Tegra Security Engine which accelerates various
AES encryption/decryption and HASH algorithms.
+config CRYPTO_DEV_XILINX_TRNG
+ tristate "Support for Xilinx True Random Generator"
+ depends on ZYNQMP_FIRMWARE || COMPILE_TEST
+ select CRYPTO_RNG
+ select HW_RANDOM
+ help
+ Xilinx Versal SoC driver provides kernel-side support for True Random Number
+ 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 CRYPTO_DEV_ZYNQMP_AES
tristate "Support for Xilinx ZynqMP AES hw accelerator"
depends on ZYNQMP_FIRMWARE || COMPILE_TEST
diff --git a/drivers/crypto/xilinx/Makefile b/drivers/crypto/xilinx/Makefile
index 730feff5b5f2..9b51636ef75e 100644
--- a/drivers/crypto/xilinx/Makefile
+++ b/drivers/crypto/xilinx/Makefile
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: GPL-2.0-only
+obj-$(CONFIG_CRYPTO_DEV_XILINX_TRNG) += xilinx-trng.o
obj-$(CONFIG_CRYPTO_DEV_ZYNQMP_AES) += zynqmp-aes-gcm.o
obj-$(CONFIG_CRYPTO_DEV_ZYNQMP_SHA3) += zynqmp-sha.o
diff --git a/drivers/crypto/xilinx/xilinx-trng.c b/drivers/crypto/xilinx/xilinx-trng.c
new file mode 100644
index 000000000000..da043e31ec17
--- /dev/null
+++ b/drivers/crypto/xilinx/xilinx-trng.c
@@ -0,0 +1,408 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * AMD Versal True Random Number Generator driver
+ * Copyright (c) 2024 - 2025 Advanced Micro Devices, Inc.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/crypto.h>
+#include <linux/firmware/xlnx-zynqmp.h>
+#include <linux/hw_random.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/mod_devicetable.h>
+#include <linux/platform_device.h>
+#include <crypto/internal/cipher.h>
+#include <crypto/internal/rng.h>
+#include <crypto/aes.h>
+#include <crypto/drbg.h>
+
+/* TRNG Registers Offsets */
+#define TRNG_STATUS_OFFSET 0x4U
+#define TRNG_CTRL_OFFSET 0x8U
+#define TRNG_EXT_SEED_OFFSET 0x40U
+#define TRNG_PER_STRNG_OFFSET 0x80U
+#define TRNG_CORE_OUTPUT_OFFSET 0xC0U
+#define TRNG_RESET_OFFSET 0xD0U
+#define TRNG_OSC_EN_OFFSET 0xD4U
+
+/* Mask values */
+#define TRNG_RESET_VAL_MASK BIT(0)
+#define TRNG_OSC_EN_VAL_MASK BIT(0)
+#define TRNG_CTRL_PRNGSRST_MASK BIT(0)
+#define TRNG_CTRL_EUMODE_MASK BIT(8)
+#define TRNG_CTRL_TRSSEN_MASK BIT(2)
+#define TRNG_CTRL_PRNGSTART_MASK BIT(5)
+#define TRNG_CTRL_PRNGXS_MASK BIT(3)
+#define TRNG_CTRL_PRNGMODE_MASK BIT(7)
+#define TRNG_STATUS_DONE_MASK BIT(0)
+#define TRNG_STATUS_QCNT_MASK GENMASK(11, 9)
+#define TRNG_STATUS_QCNT_16_BYTES 0x800
+
+/* Sizes in bytes */
+#define TRNG_SEED_LEN_BYTES 48U
+#define TRNG_ENTROPY_SEED_LEN_BYTES 64U
+#define TRNG_SEC_STRENGTH_SHIFT 5U
+#define TRNG_SEC_STRENGTH_BYTES BIT(TRNG_SEC_STRENGTH_SHIFT)
+#define TRNG_BYTES_PER_REG 4U
+#define TRNG_RESET_DELAY 10
+#define TRNG_NUM_INIT_REGS 12U
+#define TRNG_READ_4_WORD 4
+#define TRNG_DATA_READ_DELAY 8000
+
+struct xilinx_rng {
+ void __iomem *rng_base;
+ struct device *dev;
+ struct mutex lock; /* Protect access to TRNG device */
+ struct hwrng trng;
+};
+
+struct xilinx_rng_ctx {
+ struct xilinx_rng *rng;
+};
+
+static struct xilinx_rng *xilinx_rng_dev;
+
+static void xtrng_readwrite32(void __iomem *addr, u32 mask, u8 value)
+{
+ u32 val;
+
+ val = ioread32(addr);
+ val = (val & (~mask)) | (mask & value);
+ iowrite32(val, addr);
+}
+
+static void xtrng_trng_reset(void __iomem *addr)
+{
+ xtrng_readwrite32(addr + TRNG_RESET_OFFSET, TRNG_RESET_VAL_MASK, TRNG_RESET_VAL_MASK);
+ udelay(TRNG_RESET_DELAY);
+ xtrng_readwrite32(addr + TRNG_RESET_OFFSET, TRNG_RESET_VAL_MASK, 0);
+}
+
+static void xtrng_hold_reset(void __iomem *addr)
+{
+ xtrng_readwrite32(addr + TRNG_CTRL_OFFSET, TRNG_CTRL_PRNGSRST_MASK,
+ TRNG_CTRL_PRNGSRST_MASK);
+ iowrite32(TRNG_RESET_VAL_MASK, addr + TRNG_RESET_OFFSET);
+ udelay(TRNG_RESET_DELAY);
+}
+
+static void xtrng_softreset(struct xilinx_rng *rng)
+{
+ xtrng_readwrite32(rng->rng_base + TRNG_CTRL_OFFSET, TRNG_CTRL_PRNGSRST_MASK,
+ TRNG_CTRL_PRNGSRST_MASK);
+ udelay(TRNG_RESET_DELAY);
+ 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)
+{
+ int read = 0, ret;
+ int timeout = 1;
+ int i, idx;
+ u32 val;
+
+ if (wait)
+ timeout = TRNG_DATA_READ_DELAY;
+
+ for (i = 0; i < (blocks32 * 2); i++) {
+ /* TRNG core generate data in 16 bytes. Read twice to complete 32 bytes read */
+ ret = readl_poll_timeout(rng_base + TRNG_STATUS_OFFSET, val,
+ (val & TRNG_STATUS_QCNT_MASK) ==
+ TRNG_STATUS_QCNT_16_BYTES, !!wait, timeout);
+ if (ret)
+ break;
+
+ for (idx = 0; idx < TRNG_READ_4_WORD; idx++) {
+ *(buf + read) = cpu_to_be32(ioread32(rng_base + TRNG_CORE_OUTPUT_OFFSET));
+ read += 1;
+ }
+ }
+ return read * 4;
+}
+
+static int xtrng_collect_random_data(struct xilinx_rng *rng, u8 *rand_gen_buf,
+ int no_of_random_bytes, bool wait)
+{
+ u8 randbuf[TRNG_SEC_STRENGTH_BYTES];
+ int byteleft, blocks, count = 0;
+ int ret;
+
+ byteleft = no_of_random_bytes & (TRNG_SEC_STRENGTH_BYTES - 1);
+ blocks = no_of_random_bytes >> TRNG_SEC_STRENGTH_SHIFT;
+ 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;
+ count += ret;
+ }
+
+ if (byteleft) {
+ ret = xtrng_readblock32(rng->rng_base, (__be32 *)randbuf, 1, wait);
+ if (!ret)
+ return count;
+ memcpy(rand_gen_buf + (blocks * TRNG_SEC_STRENGTH_BYTES), randbuf, byteleft);
+ count += byteleft;
+ }
+
+ xtrng_readwrite32(rng->rng_base + TRNG_CTRL_OFFSET,
+ TRNG_CTRL_PRNGMODE_MASK | TRNG_CTRL_PRNGSTART_MASK, 0U);
+
+ return count;
+}
+
+static void xtrng_write_multiple_registers(void __iomem *base_addr, u32 *values, size_t n)
+{
+ void __iomem *reg_addr;
+ size_t i;
+
+ /* Write seed value into EXTERNAL_SEED Registers in big endian format */
+ for (i = 0; i < n; i++) {
+ reg_addr = (base_addr + ((n - 1 - i) * TRNG_BYTES_PER_REG));
+ iowrite32((u32 __force)(cpu_to_be32(values[i])), reg_addr);
+ }
+}
+
+static void xtrng_enable_entropy(struct xilinx_rng *rng)
+{
+ iowrite32(TRNG_OSC_EN_VAL_MASK, rng->rng_base + TRNG_OSC_EN_OFFSET);
+ xtrng_softreset(rng);
+ iowrite32(TRNG_CTRL_EUMODE_MASK | TRNG_CTRL_TRSSEN_MASK, rng->rng_base + TRNG_CTRL_OFFSET);
+}
+
+static int xtrng_reseed_internal(struct xilinx_rng *rng)
+{
+ u8 entropy[TRNG_ENTROPY_SEED_LEN_BYTES];
+ u32 entropylen = TRNG_SEED_LEN_BYTES;
+ struct drbg_string data;
+ LIST_HEAD(seedlist);
+ u32 val;
+ int ret;
+
+ drbg_string_fill(&data, entropy, entropylen);
+ list_add_tail(&data.list, &seedlist);
+ memset(entropy, 0, sizeof(entropy));
+ xtrng_enable_entropy(rng);
+
+ /* collect random data to use it as entropy (input for DF) */
+ ret = xtrng_collect_random_data(rng, entropy, TRNG_SEED_LEN_BYTES, true);
+ if (ret != TRNG_SEED_LEN_BYTES)
+ return -EINVAL;
+
+ xtrng_write_multiple_registers(rng->rng_base + TRNG_EXT_SEED_OFFSET,
+ (u32 *)entropy, TRNG_NUM_INIT_REGS);
+ /* select reseed operation */
+ iowrite32(TRNG_CTRL_PRNGXS_MASK, rng->rng_base + TRNG_CTRL_OFFSET);
+
+ /* Start the reseed operation with above configuration and wait for STATUS.Done bit to be
+ * set. Monitor STATUS.CERTF bit, if set indicates SP800-90B entropy health test has failed.
+ */
+ xtrng_readwrite32(rng->rng_base + TRNG_CTRL_OFFSET, TRNG_CTRL_PRNGSTART_MASK,
+ TRNG_CTRL_PRNGSTART_MASK);
+
+ ret = readl_poll_timeout(rng->rng_base + TRNG_STATUS_OFFSET, val,
+ (val & TRNG_STATUS_DONE_MASK) == TRNG_STATUS_DONE_MASK,
+ 1U, 15000U);
+ if (ret)
+ return ret;
+
+ xtrng_readwrite32(rng->rng_base + TRNG_CTRL_OFFSET, TRNG_CTRL_PRNGSTART_MASK, 0U);
+
+ return 0;
+}
+
+static int xtrng_random_bytes_generate(struct xilinx_rng *rng, u8 *rand_buf_ptr,
+ u32 rand_buf_size, int wait)
+{
+ int nbytes;
+ int ret;
+
+ xtrng_readwrite32(rng->rng_base + TRNG_CTRL_OFFSET,
+ TRNG_CTRL_PRNGMODE_MASK | TRNG_CTRL_PRNGXS_MASK,
+ TRNG_CTRL_PRNGMODE_MASK | TRNG_CTRL_PRNGXS_MASK);
+ nbytes = xtrng_collect_random_data(rng, rand_buf_ptr, rand_buf_size, wait);
+
+ ret = xtrng_reseed_internal(rng);
+ if (ret) {
+ dev_err(rng->dev, "Re-seed fail\n");
+ return ret;
+ }
+
+ return nbytes;
+}
+
+static int xtrng_trng_generate(struct crypto_rng *tfm, const u8 *src, u32 slen,
+ u8 *dst, u32 dlen)
+{
+ struct xilinx_rng_ctx *ctx = crypto_rng_ctx(tfm);
+ int ret;
+
+ mutex_lock(&ctx->rng->lock);
+ ret = xtrng_random_bytes_generate(ctx->rng, dst, dlen, true);
+ mutex_unlock(&ctx->rng->lock);
+
+ return ret < 0 ? ret : 0;
+}
+
+static int xtrng_trng_seed(struct crypto_rng *tfm, const u8 *seed, unsigned int slen)
+{
+ return 0;
+}
+
+static int xtrng_trng_init(struct crypto_tfm *rtfm)
+{
+ struct xilinx_rng_ctx *ctx = crypto_tfm_ctx(rtfm);
+
+ ctx->rng = xilinx_rng_dev;
+
+ return 0;
+}
+
+static struct rng_alg xtrng_trng_alg = {
+ .generate = xtrng_trng_generate,
+ .seed = xtrng_trng_seed,
+ .seedsize = 0,
+ .base = {
+ .cra_name = "stdrng",
+ .cra_driver_name = "xilinx-trng",
+ .cra_priority = 300,
+ .cra_ctxsize = sizeof(struct xilinx_rng_ctx),
+ .cra_module = THIS_MODULE,
+ .cra_init = xtrng_trng_init,
+ },
+};
+
+static int xtrng_hwrng_trng_read(struct hwrng *hwrng, void *data, size_t max, bool wait)
+{
+ u8 buf[TRNG_SEC_STRENGTH_BYTES];
+ struct xilinx_rng *rng;
+ int ret = -EINVAL, i = 0;
+
+ rng = container_of(hwrng, struct xilinx_rng, trng);
+ /* Return in case wait not set and lock not available. */
+ if (!mutex_trylock(&rng->lock) && !wait)
+ return 0;
+ else if (!mutex_is_locked(&rng->lock) && wait)
+ mutex_lock(&rng->lock);
+
+ while (i < max) {
+ ret = xtrng_random_bytes_generate(rng, buf, TRNG_SEC_STRENGTH_BYTES, wait);
+ if (ret < 0)
+ break;
+
+ memcpy(data + i, buf, min_t(int, ret, (max - i)));
+ i += min_t(int, ret, (max - i));
+ }
+ mutex_unlock(&rng->lock);
+
+ return ret;
+}
+
+static int xtrng_hwrng_register(struct hwrng *trng)
+{
+ int ret;
+
+ trng->name = "Xilinx Versal Crypto Engine TRNG";
+ trng->read = xtrng_hwrng_trng_read;
+
+ ret = hwrng_register(trng);
+ if (ret)
+ pr_err("Fail to register the TRNG\n");
+
+ return ret;
+}
+
+static void xtrng_hwrng_unregister(struct hwrng *trng)
+{
+ hwrng_unregister(trng);
+}
+
+static int xtrng_probe(struct platform_device *pdev)
+{
+ struct xilinx_rng *rng;
+ int ret;
+
+ rng = devm_kzalloc(&pdev->dev, sizeof(*rng), GFP_KERNEL);
+ if (!rng)
+ return -ENOMEM;
+
+ rng->dev = &pdev->dev;
+ rng->rng_base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(rng->rng_base)) {
+ dev_err(&pdev->dev, "Failed to map resource %ld\n", PTR_ERR(rng->rng_base));
+ return PTR_ERR(rng->rng_base);
+ }
+
+ xtrng_trng_reset(rng->rng_base);
+ ret = xtrng_reseed_internal(rng);
+ if (ret) {
+ dev_err(&pdev->dev, "TRNG Seed fail\n");
+ return ret;
+ }
+
+ xilinx_rng_dev = rng;
+ mutex_init(&rng->lock);
+ ret = crypto_register_rng(&xtrng_trng_alg);
+ if (ret) {
+ dev_err(&pdev->dev, "Crypto Random device registration failed: %d\n", ret);
+ return ret;
+ }
+ ret = xtrng_hwrng_register(&rng->trng);
+ if (ret) {
+ dev_err(&pdev->dev, "HWRNG device registration failed: %d\n", ret);
+ goto crypto_rng_free;
+ }
+ platform_set_drvdata(pdev, rng);
+
+ return 0;
+
+crypto_rng_free:
+ crypto_unregister_rng(&xtrng_trng_alg);
+
+ return ret;
+}
+
+static void xtrng_remove(struct platform_device *pdev)
+{
+ struct xilinx_rng *rng;
+ u32 zero[TRNG_NUM_INIT_REGS] = { };
+
+ rng = platform_get_drvdata(pdev);
+ xtrng_hwrng_unregister(&rng->trng);
+ crypto_unregister_rng(&xtrng_trng_alg);
+ xtrng_write_multiple_registers(rng->rng_base + TRNG_EXT_SEED_OFFSET, zero,
+ TRNG_NUM_INIT_REGS);
+ xtrng_write_multiple_registers(rng->rng_base + TRNG_PER_STRNG_OFFSET, zero,
+ TRNG_NUM_INIT_REGS);
+ xtrng_hold_reset(rng->rng_base);
+ xilinx_rng_dev = NULL;
+}
+
+static const struct of_device_id xtrng_of_match[] = {
+ { .compatible = "xlnx,versal-trng", },
+ {},
+};
+
+MODULE_DEVICE_TABLE(of, xtrng_of_match);
+
+static struct platform_driver xtrng_driver = {
+ .driver = {
+ .name = "xlnx,versal-trng",
+ .of_match_table = xtrng_of_match,
+ },
+ .probe = xtrng_probe,
+ .remove = xtrng_remove,
+};
+
+module_platform_driver(xtrng_driver);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Harsh Jain <h.jain@amd.com>");
+MODULE_AUTHOR("Mounika Botcha <mounika.botcha@amd.com>");
+MODULE_DESCRIPTION("True Random Number Generator Driver");
--
2.34.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v3 3/3] crypto: drbg: Export CTR DRBG DF functions
2025-06-12 5:25 [PATCH v3 0/3] Add Versal TRNG driver Harsh Jain
2025-06-12 5:25 ` [PATCH v3 1/3] dt-bindings: crypto: Add node for True Random Number Generator Harsh Jain
2025-06-12 5:25 ` [PATCH v3 2/3] crypto: xilinx: Add TRNG driver for Versal Harsh Jain
@ 2025-06-12 5:25 ` Harsh Jain
2025-07-07 3:17 ` Herbert Xu
2 siblings, 1 reply; 8+ messages in thread
From: Harsh Jain @ 2025-06-12 5:25 UTC (permalink / raw)
To: herbert, davem, linux-crypto, devicetree, mounika.botcha,
sarat.chand.savitala, mohan.dhanawade, michal.simek
Cc: Harsh Jain
Export drbg_ctr_df() derivative function to re-use it in xilinx trng
driver. Changes has been tested by enabling CONFIG_CRYPTO_USER_API_RNG_CAVP
Signed-off-by: Harsh Jain <h.jain@amd.com>
---
crypto/drbg.c | 108 +++++++++++++++-------------
drivers/crypto/Kconfig | 2 +
drivers/crypto/xilinx/xilinx-trng.c | 32 ++++++++-
include/crypto/drbg.h | 15 ++++
4 files changed, 103 insertions(+), 54 deletions(-)
diff --git a/crypto/drbg.c b/crypto/drbg.c
index dbe4c8bb5ceb..322c630c54b8 100644
--- a/crypto/drbg.c
+++ b/crypto/drbg.c
@@ -294,10 +294,11 @@ MODULE_ALIAS_CRYPTO("drbg_nopr_ctr_aes192");
MODULE_ALIAS_CRYPTO("drbg_pr_ctr_aes128");
MODULE_ALIAS_CRYPTO("drbg_nopr_ctr_aes128");
-static void drbg_kcapi_symsetkey(struct drbg_state *drbg,
- const unsigned char *key);
-static int drbg_kcapi_sym(struct drbg_state *drbg, unsigned char *outval,
- const struct drbg_string *in);
+static void drbg_kcapi_symsetkey(struct crypto_cipher *tfm,
+ const unsigned char *key,
+ u8 keylen);
+static int drbg_kcapi_sym(struct crypto_cipher *tfm, unsigned char *outval,
+ const struct drbg_string *in, u8 blocklen_bytes);
static int drbg_init_sym_kernel(struct drbg_state *drbg);
static int drbg_fini_sym_kernel(struct drbg_state *drbg);
static int drbg_kcapi_sym_ctr(struct drbg_state *drbg,
@@ -306,28 +307,31 @@ static int drbg_kcapi_sym_ctr(struct drbg_state *drbg,
#define DRBG_OUTSCRATCHLEN 256
/* BCC function for CTR DRBG as defined in 10.4.3 */
-static int drbg_ctr_bcc(struct drbg_state *drbg,
+
+static int drbg_ctr_bcc(struct crypto_cipher *tfm,
unsigned char *out, const unsigned char *key,
- struct list_head *in)
+ struct list_head *in,
+ u8 blocklen_bytes,
+ u8 keylen)
{
int ret = 0;
struct drbg_string *curr = NULL;
struct drbg_string data;
short cnt = 0;
- drbg_string_fill(&data, out, drbg_blocklen(drbg));
+ drbg_string_fill(&data, out, blocklen_bytes);
/* 10.4.3 step 2 / 4 */
- drbg_kcapi_symsetkey(drbg, key);
+ drbg_kcapi_symsetkey(tfm, key, keylen);
list_for_each_entry(curr, in, list) {
const unsigned char *pos = curr->buf;
size_t len = curr->len;
/* 10.4.3 step 4.1 */
while (len) {
/* 10.4.3 step 4.2 */
- if (drbg_blocklen(drbg) == cnt) {
+ if (blocklen_bytes == cnt) {
cnt = 0;
- ret = drbg_kcapi_sym(drbg, out, &data);
+ ret = drbg_kcapi_sym(tfm, out, &data, blocklen_bytes);
if (ret)
return ret;
}
@@ -339,13 +343,13 @@ static int drbg_ctr_bcc(struct drbg_state *drbg,
}
/* 10.4.3 step 4.2 for last block */
if (cnt)
- ret = drbg_kcapi_sym(drbg, out, &data);
+ ret = drbg_kcapi_sym(tfm, out, &data, blocklen_bytes);
return ret;
}
/*
- * scratchpad usage: drbg_ctr_update is interlinked with drbg_ctr_df
+ * scratchpad usage: drbg_ctr_update is interlinked with crypto_drbg_ctr_df
* (and drbg_ctr_bcc, but this function does not need any temporary buffers),
* the scratchpad is used as follows:
* drbg_ctr_update:
@@ -362,7 +366,7 @@ static int drbg_ctr_bcc(struct drbg_state *drbg,
* drbg_statelen(drbg) + drbg_blocklen(drbg)
* length: drbg_statelen(drbg)
*
- * drbg_ctr_df:
+ * crypto_drbg_ctr_df:
* pad
* start: df_data + drbg_statelen(drbg)
* length: drbg_blocklen(drbg)
@@ -381,21 +385,24 @@ static int drbg_ctr_bcc(struct drbg_state *drbg,
* the final output of all BCC rounds are truncated).
* Therefore, add drbg_blocklen(drbg) to cover all
* possibilities.
+ * refer to crypto_drbg_ctr_df_datalen() to get required length
*/
/* Derivation Function for CTR DRBG as defined in 10.4.2 */
-static int drbg_ctr_df(struct drbg_state *drbg,
+int crypto_drbg_ctr_df(struct crypto_cipher *tfm,
unsigned char *df_data, size_t bytes_to_return,
- struct list_head *seedlist)
+ struct list_head *seedlist,
+ u8 blocklen_bytes,
+ u8 statelen)
{
int ret = -EFAULT;
unsigned char L_N[8];
/* S3 is input */
struct drbg_string S1, S2, S4, cipherin;
LIST_HEAD(bcc_list);
- unsigned char *pad = df_data + drbg_statelen(drbg);
- unsigned char *iv = pad + drbg_blocklen(drbg);
- unsigned char *temp = iv + drbg_blocklen(drbg);
+ unsigned char *pad = df_data + statelen;
+ unsigned char *iv = pad + blocklen_bytes;
+ unsigned char *temp = iv + blocklen_bytes;
size_t padlen = 0;
unsigned int templen = 0;
/* 10.4.2 step 7 */
@@ -410,10 +417,11 @@ static int drbg_ctr_df(struct drbg_state *drbg,
size_t generated_len = 0;
size_t inputlen = 0;
struct drbg_string *seed = NULL;
+ u8 keylen;
- memset(pad, 0, drbg_blocklen(drbg));
- memset(iv, 0, drbg_blocklen(drbg));
-
+ memset(pad, 0, blocklen_bytes);
+ memset(iv, 0, blocklen_bytes);
+ keylen = statelen - blocklen_bytes;
/* 10.4.2 step 1 is implicit as we work byte-wise */
/* 10.4.2 step 2 */
@@ -429,10 +437,10 @@ static int drbg_ctr_df(struct drbg_state *drbg,
drbg_cpu_to_be32(bytes_to_return, &L_N[4]);
/* 10.4.2 step 5: length is L_N, input_string, one byte, padding */
- padlen = (inputlen + sizeof(L_N) + 1) % (drbg_blocklen(drbg));
+ padlen = (inputlen + sizeof(L_N) + 1) % (blocklen_bytes);
/* wrap the padlen appropriately */
if (padlen)
- padlen = drbg_blocklen(drbg) - padlen;
+ padlen = blocklen_bytes - padlen;
/*
* pad / padlen contains the 0x80 byte and the following zero bytes.
* As the calculated padlen value only covers the number of zero
@@ -442,7 +450,7 @@ static int drbg_ctr_df(struct drbg_state *drbg,
pad[0] = 0x80;
/* 10.4.2 step 4 -- first fill the linked list and then order it */
- drbg_string_fill(&S1, iv, drbg_blocklen(drbg));
+ drbg_string_fill(&S1, iv, blocklen_bytes);
list_add_tail(&S1.list, &bcc_list);
drbg_string_fill(&S2, L_N, sizeof(L_N));
list_add_tail(&S2.list, &bcc_list);
@@ -451,7 +459,7 @@ static int drbg_ctr_df(struct drbg_state *drbg,
list_add_tail(&S4.list, &bcc_list);
/* 10.4.2 step 9 */
- while (templen < (drbg_keylen(drbg) + (drbg_blocklen(drbg)))) {
+ while (templen < (keylen + (blocklen_bytes))) {
/*
* 10.4.2 step 9.1 - the padding is implicit as the buffer
* holds zeros after allocation -- even the increment of i
@@ -459,22 +467,23 @@ static int drbg_ctr_df(struct drbg_state *drbg,
*/
drbg_cpu_to_be32(i, iv);
/* 10.4.2 step 9.2 -- BCC and concatenation with temp */
- ret = drbg_ctr_bcc(drbg, temp + templen, K, &bcc_list);
+ ret = drbg_ctr_bcc(tfm, temp + templen, K, &bcc_list,
+ blocklen_bytes, keylen);
if (ret)
goto out;
/* 10.4.2 step 9.3 */
i++;
- templen += drbg_blocklen(drbg);
+ templen += blocklen_bytes;
}
/* 10.4.2 step 11 */
- X = temp + (drbg_keylen(drbg));
- drbg_string_fill(&cipherin, X, drbg_blocklen(drbg));
+ X = temp + (keylen);
+ drbg_string_fill(&cipherin, X, blocklen_bytes);
/* 10.4.2 step 12: overwriting of outval is implemented in next step */
/* 10.4.2 step 13 */
- drbg_kcapi_symsetkey(drbg, temp);
+ drbg_kcapi_symsetkey(tfm, temp, keylen);
while (generated_len < bytes_to_return) {
short blocklen = 0;
/*
@@ -482,12 +491,12 @@ static int drbg_ctr_df(struct drbg_state *drbg,
* implicit as the key is only drbg_blocklen in size based on
* the implementation of the cipher function callback
*/
- ret = drbg_kcapi_sym(drbg, X, &cipherin);
+ ret = drbg_kcapi_sym(tfm, X, &cipherin, blocklen_bytes);
if (ret)
goto out;
- blocklen = (drbg_blocklen(drbg) <
+ blocklen = (blocklen_bytes <
(bytes_to_return - generated_len)) ?
- drbg_blocklen(drbg) :
+ blocklen_bytes :
(bytes_to_return - generated_len);
/* 10.4.2 step 13.2 and 14 */
memcpy(df_data + generated_len, X, blocklen);
@@ -497,11 +506,12 @@ static int drbg_ctr_df(struct drbg_state *drbg,
ret = 0;
out:
- memset(iv, 0, drbg_blocklen(drbg));
- memset(temp, 0, drbg_statelen(drbg) + drbg_blocklen(drbg));
- memset(pad, 0, drbg_blocklen(drbg));
+ memset(iv, 0, blocklen_bytes);
+ memset(temp, 0, statelen + blocklen_bytes);
+ memset(pad, 0, blocklen_bytes);
return ret;
}
+EXPORT_SYMBOL_GPL(crypto_drbg_ctr_df);
/*
* update function of CTR DRBG as defined in 10.2.1.2
@@ -548,7 +558,9 @@ static int drbg_ctr_update(struct drbg_state *drbg, struct list_head *seed,
/* 10.2.1.3.2 step 2 and 10.2.1.4.2 step 2 */
if (seed) {
- ret = drbg_ctr_df(drbg, df_data, drbg_statelen(drbg), seed);
+ ret = crypto_drbg_ctr_df(drbg->priv_data, df_data, drbg_statelen(drbg), seed,
+ drbg_blocklen(drbg),
+ drbg_statelen(drbg));
if (ret)
goto out;
}
@@ -1310,10 +1322,8 @@ static inline int drbg_alloc_state(struct drbg_state *drbg)
sb_size = 0;
else if (drbg->core->flags & DRBG_CTR)
sb_size = drbg_statelen(drbg) + drbg_blocklen(drbg) + /* temp */
- drbg_statelen(drbg) + /* df_data */
- drbg_blocklen(drbg) + /* pad */
- drbg_blocklen(drbg) + /* iv */
- drbg_statelen(drbg) + drbg_blocklen(drbg); /* temp */
+ crypto_drbg_ctr_df_datalen(drbg_statelen(drbg),
+ drbg_blocklen(drbg));
else
sb_size = drbg_statelen(drbg) + drbg_blocklen(drbg);
@@ -1800,21 +1810,17 @@ static int drbg_init_sym_kernel(struct drbg_state *drbg)
return alignmask;
}
-static void drbg_kcapi_symsetkey(struct drbg_state *drbg,
- const unsigned char *key)
+static void drbg_kcapi_symsetkey(struct crypto_cipher *tfm,
+ const unsigned char *key, u8 keylen)
{
- struct crypto_cipher *tfm = drbg->priv_data;
-
- crypto_cipher_setkey(tfm, key, (drbg_keylen(drbg)));
+ crypto_cipher_setkey(tfm, key, keylen);
}
-static int drbg_kcapi_sym(struct drbg_state *drbg, unsigned char *outval,
- const struct drbg_string *in)
+static int drbg_kcapi_sym(struct crypto_cipher *tfm, unsigned char *outval,
+ const struct drbg_string *in, u8 blocklen_bytes)
{
- struct crypto_cipher *tfm = drbg->priv_data;
-
/* there is only component in *in */
- BUG_ON(in->len < drbg_blocklen(drbg));
+ BUG_ON(in->len < blocklen_bytes);
crypto_cipher_encrypt_one(tfm, outval, in->buf);
return 0;
}
diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index 209720b42ec6..cfbc06451fec 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -714,6 +714,8 @@ config CRYPTO_DEV_TEGRA
config CRYPTO_DEV_XILINX_TRNG
tristate "Support for Xilinx True Random Generator"
depends on ZYNQMP_FIRMWARE || COMPILE_TEST
+ select CRYPTO_DRBG_MENU
+ select CRYPTO_DRBG_CTR
select CRYPTO_RNG
select HW_RANDOM
help
diff --git a/drivers/crypto/xilinx/xilinx-trng.c b/drivers/crypto/xilinx/xilinx-trng.c
index da043e31ec17..e339ee95d01c 100644
--- a/drivers/crypto/xilinx/xilinx-trng.c
+++ b/drivers/crypto/xilinx/xilinx-trng.c
@@ -57,6 +57,8 @@
struct xilinx_rng {
void __iomem *rng_base;
struct device *dev;
+ unsigned char *scratchpadbuf;
+ struct crypto_cipher *tfm;
struct mutex lock; /* Protect access to TRNG device */
struct hwrng trng;
};
@@ -195,9 +197,14 @@ static int xtrng_reseed_internal(struct xilinx_rng *rng)
ret = xtrng_collect_random_data(rng, entropy, TRNG_SEED_LEN_BYTES, true);
if (ret != TRNG_SEED_LEN_BYTES)
return -EINVAL;
+ ret = crypto_drbg_ctr_df(rng->tfm, rng->scratchpadbuf,
+ TRNG_SEED_LEN_BYTES, &seedlist, AES_BLOCK_SIZE,
+ TRNG_SEED_LEN_BYTES);
+ if (ret)
+ return ret;
xtrng_write_multiple_registers(rng->rng_base + TRNG_EXT_SEED_OFFSET,
- (u32 *)entropy, TRNG_NUM_INIT_REGS);
+ (u32 *)rng->scratchpadbuf, TRNG_NUM_INIT_REGS);
/* select reseed operation */
iowrite32(TRNG_CTRL_PRNGXS_MASK, rng->rng_base + TRNG_CTRL_OFFSET);
@@ -327,6 +334,7 @@ static void xtrng_hwrng_unregister(struct hwrng *trng)
static int xtrng_probe(struct platform_device *pdev)
{
struct xilinx_rng *rng;
+ size_t sb_size;
int ret;
rng = devm_kzalloc(&pdev->dev, sizeof(*rng), GFP_KERNEL);
@@ -340,11 +348,24 @@ static int xtrng_probe(struct platform_device *pdev)
return PTR_ERR(rng->rng_base);
}
+ rng->tfm = crypto_alloc_cipher("aes", 0, 0);
+ if (IS_ERR(rng->tfm)) {
+ pr_info("DRBG: could not allocate cipher TFM handle:\n");
+ return PTR_ERR(rng->tfm);
+ }
+
+ sb_size = crypto_drbg_ctr_df_datalen(TRNG_SEED_LEN_BYTES, AES_BLOCK_SIZE);
+ rng->scratchpadbuf = devm_kzalloc(&pdev->dev, sb_size, GFP_KERNEL);
+ if (!rng->scratchpadbuf) {
+ ret = -ENOMEM;
+ goto cipher_cleanup;
+ }
+
xtrng_trng_reset(rng->rng_base);
ret = xtrng_reseed_internal(rng);
if (ret) {
dev_err(&pdev->dev, "TRNG Seed fail\n");
- return ret;
+ goto cipher_cleanup;
}
xilinx_rng_dev = rng;
@@ -352,8 +373,9 @@ static int xtrng_probe(struct platform_device *pdev)
ret = crypto_register_rng(&xtrng_trng_alg);
if (ret) {
dev_err(&pdev->dev, "Crypto Random device registration failed: %d\n", ret);
- return ret;
+ goto cipher_cleanup;
}
+
ret = xtrng_hwrng_register(&rng->trng);
if (ret) {
dev_err(&pdev->dev, "HWRNG device registration failed: %d\n", ret);
@@ -366,6 +388,9 @@ static int xtrng_probe(struct platform_device *pdev)
crypto_rng_free:
crypto_unregister_rng(&xtrng_trng_alg);
+cipher_cleanup:
+ crypto_free_cipher(rng->tfm);
+
return ret;
}
@@ -377,6 +402,7 @@ static void xtrng_remove(struct platform_device *pdev)
rng = platform_get_drvdata(pdev);
xtrng_hwrng_unregister(&rng->trng);
crypto_unregister_rng(&xtrng_trng_alg);
+ crypto_free_cipher(rng->tfm);
xtrng_write_multiple_registers(rng->rng_base + TRNG_EXT_SEED_OFFSET, zero,
TRNG_NUM_INIT_REGS);
xtrng_write_multiple_registers(rng->rng_base + TRNG_PER_STRNG_OFFSET, zero,
diff --git a/include/crypto/drbg.h b/include/crypto/drbg.h
index af5ad51d3eef..978a4a0c34e0 100644
--- a/include/crypto/drbg.h
+++ b/include/crypto/drbg.h
@@ -53,6 +53,7 @@
#include <linux/mutex.h>
#include <linux/list.h>
#include <linux/workqueue.h>
+#include <crypto/internal/cipher.h>
/*
* Concatenation Helper and string operation helper
@@ -264,6 +265,14 @@ static inline int crypto_drbg_reset_test(struct crypto_rng *drng,
return crypto_rng_reset(drng, pers->buf, pers->len);
}
+static inline int crypto_drbg_ctr_df_datalen(u8 statelen, u8 blocklen)
+{
+ return statelen + /* df_data */
+ blocklen + /* pad */
+ blocklen + /* iv */
+ statelen + blocklen; /* temp */
+}
+
/* DRBG type flags */
#define DRBG_CTR ((drbg_flag_t)1<<0)
#define DRBG_HMAC ((drbg_flag_t)1<<1)
@@ -283,4 +292,10 @@ enum drbg_prefixes {
DRBG_PREFIX3
};
+int crypto_drbg_ctr_df(struct crypto_cipher *tfm,
+ unsigned char *df_data, size_t bytes_to_return,
+ struct list_head *seedlist,
+ u8 blocklen_bytes,
+ u8 statelen);
+
#endif /* _DRBG_H */
--
2.34.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v3 1/3] dt-bindings: crypto: Add node for True Random Number Generator
2025-06-12 5:25 ` [PATCH v3 1/3] dt-bindings: crypto: Add node for True Random Number Generator Harsh Jain
@ 2025-06-17 7:11 ` Krzysztof Kozlowski
0 siblings, 0 replies; 8+ messages in thread
From: Krzysztof Kozlowski @ 2025-06-17 7:11 UTC (permalink / raw)
To: Harsh Jain
Cc: herbert, davem, linux-crypto, devicetree, mounika.botcha,
sarat.chand.savitala, mohan.dhanawade, michal.simek
On Thu, Jun 12, 2025 at 10:55:40AM GMT, Harsh Jain wrote:
> From: Mounika Botcha <mounika.botcha@amd.com>
>
> Add TRNG node compatible string and reg properities.
>
> Signed-off-by: Mounika Botcha <mounika.botcha@amd.com>
> Signed-off-by: Harsh Jain <h.jain@amd.com>
> ---
> .../bindings/crypto/xlnx,versal-trng.yaml | 36 +++++++++++++++++++
> 1 file changed, 36 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/crypto/xlnx,versal-trng.yaml
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v3 3/3] crypto: drbg: Export CTR DRBG DF functions
2025-06-12 5:25 ` [PATCH v3 3/3] crypto: drbg: Export CTR DRBG DF functions Harsh Jain
@ 2025-07-07 3:17 ` Herbert Xu
2025-07-14 6:05 ` Jain, Harsh (AECG-SSW)
0 siblings, 1 reply; 8+ messages in thread
From: Herbert Xu @ 2025-07-07 3:17 UTC (permalink / raw)
To: Harsh Jain
Cc: davem, linux-crypto, devicetree, mounika.botcha,
sarat.chand.savitala, mohan.dhanawade, michal.simek,
Stephan Mueller
On Thu, Jun 12, 2025 at 10:55:42AM +0530, Harsh Jain wrote:
> Export drbg_ctr_df() derivative function to re-use it in xilinx trng
> driver. Changes has been tested by enabling CONFIG_CRYPTO_USER_API_RNG_CAVP
>
> Signed-off-by: Harsh Jain <h.jain@amd.com>
> ---
> crypto/drbg.c | 108 +++++++++++++++-------------
> drivers/crypto/Kconfig | 2 +
> drivers/crypto/xilinx/xilinx-trng.c | 32 ++++++++-
> include/crypto/drbg.h | 15 ++++
> 4 files changed, 103 insertions(+), 54 deletions(-)
Please move the df function out into its own module like crypto/hkdf.c.
You should also keep the drbg changes to a minimum.
Thanks,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply [flat|nested] 8+ messages in thread
* RE: [PATCH v3 3/3] crypto: drbg: Export CTR DRBG DF functions
2025-07-07 3:17 ` Herbert Xu
@ 2025-07-14 6:05 ` Jain, Harsh (AECG-SSW)
2025-07-16 22:28 ` Herbert Xu
0 siblings, 1 reply; 8+ messages in thread
From: Jain, Harsh (AECG-SSW) @ 2025-07-14 6:05 UTC (permalink / raw)
To: Herbert Xu
Cc: davem@davemloft.net, linux-crypto@vger.kernel.org,
devicetree@vger.kernel.org, Botcha, Mounika,
Savitala, Sarat Chand, Dhanawade, Mohan, Simek, Michal,
Stephan Mueller
[AMD Official Use Only - AMD Internal Distribution Only]
> -----Original Message-----
> From: Herbert Xu <herbert@gondor.apana.org.au>
> Sent: Monday, July 7, 2025 8:47 AM
> To: Jain, Harsh (AECG-SSW) <h.jain@amd.com>
> Cc: davem@davemloft.net; linux-crypto@vger.kernel.org;
> devicetree@vger.kernel.org; Botcha, Mounika <Mounika.Botcha@amd.com>;
> Savitala, Sarat Chand <sarat.chand.savitala@amd.com>; Dhanawade, Mohan
> <mohan.dhanawade@amd.com>; Simek, Michal <michal.simek@amd.com>;
> Stephan Mueller <smueller@chronox.de>
> Subject: Re: [PATCH v3 3/3] crypto: drbg: Export CTR DRBG DF functions
>
> Caution: This message originated from an External Source. Use proper caution
> when opening attachments, clicking links, or responding.
>
>
> On Thu, Jun 12, 2025 at 10:55:42AM +0530, Harsh Jain wrote:
> > Export drbg_ctr_df() derivative function to re-use it in xilinx trng
> > driver. Changes has been tested by enabling
> CONFIG_CRYPTO_USER_API_RNG_CAVP
> >
> > Signed-off-by: Harsh Jain <h.jain@amd.com>
> > ---
> > crypto/drbg.c | 108 +++++++++++++++-------------
> > drivers/crypto/Kconfig | 2 +
> > drivers/crypto/xilinx/xilinx-trng.c | 32 ++++++++-
> > include/crypto/drbg.h | 15 ++++
> > 4 files changed, 103 insertions(+), 54 deletions(-)
>
> Please move the df function out into its own module like crypto/hkdf.c.
Thanks Herbert,
There is hkdf.c and kdf_sp800108.c module, Both implements different NIST Specifications and DRBG derivative function represents different NIST Specification.
Moving it to hkdf.c may not be a best fit. How about adding new module for " crypto_drbg_ctr_df ()"?
>
> You should also keep the drbg changes to a minimum.
drbg_ctr_df() needs tfm, blocklen, statelen which is currently derived from struct drbg_state.
If I updated structure drbg_state, It needs code changes in HMAC as well.
To keep code changes minimum, I added required inputs as function arguments.
Do you have any other idea in mind?
>
> Thanks,
> --
> Email: Herbert Xu <herbert@gondor.apana.org.au>
> Home Page: http://gondor.apana.org.au/~herbert/
> PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v3 3/3] crypto: drbg: Export CTR DRBG DF functions
2025-07-14 6:05 ` Jain, Harsh (AECG-SSW)
@ 2025-07-16 22:28 ` Herbert Xu
0 siblings, 0 replies; 8+ messages in thread
From: Herbert Xu @ 2025-07-16 22:28 UTC (permalink / raw)
To: Jain, Harsh (AECG-SSW)
Cc: davem@davemloft.net, linux-crypto@vger.kernel.org,
devicetree@vger.kernel.org, Botcha, Mounika,
Savitala, Sarat Chand, Dhanawade, Mohan, Simek, Michal,
Stephan Mueller
On Mon, Jul 14, 2025 at 06:05:29AM +0000, Jain, Harsh (AECG-SSW) wrote:
>
> There is hkdf.c and kdf_sp800108.c module, Both implements different NIST Specifications and DRBG derivative function represents different NIST Specification.
> Moving it to hkdf.c may not be a best fit. How about adding new module for " crypto_drbg_ctr_df ()"?
A new module is fine.
> > You should also keep the drbg changes to a minimum.
>
> drbg_ctr_df() needs tfm, blocklen, statelen which is currently derived from struct drbg_state.
> If I updated structure drbg_state, It needs code changes in HMAC as well.
> To keep code changes minimum, I added required inputs as function arguments.
> Do you have any other idea in mind?
The existing drbg_ctr_df should become a wrapper around the new
df function and all changes should be localised to it.
Cheers,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2025-07-16 22:57 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-12 5:25 [PATCH v3 0/3] Add Versal TRNG driver Harsh Jain
2025-06-12 5:25 ` [PATCH v3 1/3] dt-bindings: crypto: Add node for True Random Number Generator Harsh Jain
2025-06-17 7:11 ` Krzysztof Kozlowski
2025-06-12 5:25 ` [PATCH v3 2/3] crypto: xilinx: Add TRNG driver for Versal Harsh Jain
2025-06-12 5:25 ` [PATCH v3 3/3] crypto: drbg: Export CTR DRBG DF functions Harsh Jain
2025-07-07 3:17 ` Herbert Xu
2025-07-14 6:05 ` Jain, Harsh (AECG-SSW)
2025-07-16 22:28 ` Herbert Xu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).