[PATCH v2 0/3] Data Co-processor RNG Driver

Implemented Data Co-Processor random number generation driver.
usage command: rng <number of bytes>
Kshitiz Varshney (3): Uboot RNG Driver using Data Co-processor Added dcp_rng driver initialization code Added configs required for dcp_rng driver
arch/arm/mach-imx/mx6/soc.c | 10 ++ configs/mx6ull_14x14_evk_defconfig | 4 + configs/mx6ull_14x14_evk_plugin_defconfig | 4 + drivers/crypto/fsl/Kconfig | 10 ++ drivers/crypto/fsl/Makefile | 1 + drivers/crypto/fsl/dcp_rng.c | 182 ++++++++++++++++++++++ 6 files changed, 211 insertions(+) create mode 100644 drivers/crypto/fsl/dcp_rng.c

This commit introduces Random number generator to uboot. It uses DCP driver for number generation. RNG driver can be invoked by using below command on uboot prompt:- rng <number of bytes>
Signed-off-by: Kshitiz Varshney kshitiz.varshney@nxp.com Reviewed-by: Ye Li ye.li@nxp.com Reviewed-by: Simon Glass sjg@chromium.org --- drivers/crypto/fsl/Kconfig | 10 ++ drivers/crypto/fsl/Makefile | 1 + drivers/crypto/fsl/dcp_rng.c | 182 +++++++++++++++++++++++++++++++++++ 3 files changed, 193 insertions(+) create mode 100644 drivers/crypto/fsl/dcp_rng.c
diff --git a/drivers/crypto/fsl/Kconfig b/drivers/crypto/fsl/Kconfig index b04c70183d..91a51cc5fe 100644 --- a/drivers/crypto/fsl/Kconfig +++ b/drivers/crypto/fsl/Kconfig @@ -73,3 +73,13 @@ config FSL_CAAM_RNG reseeded from the TRNG every time random data is generated.
endif + +config FSL_DCP_RNG + bool "Enable Random Number Generator support" + depends on DM_RNG + default n + help + Enable support for the hardware based random number generator + module of the DCP. It uses the True Random Number Generator (TRNG) + and a Pseudo-Random Number Generator (PRNG) to achieve a true + randomness and cryptographic strength. diff --git a/drivers/crypto/fsl/Makefile b/drivers/crypto/fsl/Makefile index f9c3ccecfc..7a2543e16c 100644 --- a/drivers/crypto/fsl/Makefile +++ b/drivers/crypto/fsl/Makefile @@ -7,4 +7,5 @@ obj-$(CONFIG_FSL_CAAM) += jr.o fsl_hash.o jobdesc.o error.o obj-$(CONFIG_CMD_BLOB)$(CONFIG_IMX_CAAM_DEK_ENCAP) += fsl_blob.o obj-$(CONFIG_RSA_FREESCALE_EXP) += fsl_rsa.o obj-$(CONFIG_FSL_CAAM_RNG) += rng.o +obj-$(CONFIG_FSL_DCP_RNG) += dcp_rng.o obj-$(CONFIG_FSL_MFGPROT) += fsl_mfgprot.o diff --git a/drivers/crypto/fsl/dcp_rng.c b/drivers/crypto/fsl/dcp_rng.c new file mode 100644 index 0000000000..3170696015 --- /dev/null +++ b/drivers/crypto/fsl/dcp_rng.c @@ -0,0 +1,182 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * RNG driver for Freescale RNGC + * + * Copyright 2022 NXP + * + * Based on RNGC driver in drivers/char/hw_random/imx-rngc.c in Linux + */ + +#include <common.h> +#include <cpu_func.h> +#include <dm.h> +#include <rng.h> +#include <asm/cache.h> +#include <asm/io.h> +#include <dm/root.h> +#include <linux/delay.h> +#include <linux/kernel.h> + +#define DCP_RNG_MAX_FIFO_STORE_SIZE 4 +#define RNGC_VER_ID 0x0 +#define RNGC_COMMAND 0x4 +#define RNGC_CONTROL 0x8 +#define RNGC_STATUS 0xC +#define RNGC_ERROR 0x10 +#define RNGC_FIFO 0x14 + +/* the fields in the ver id register */ +#define RNGC_TYPE_SHIFT 28 + +/* the rng_type field */ +#define RNGC_TYPE_RNGB 0x1 +#define RNGC_TYPE_RNGC 0x2 + +#define RNGC_CMD_CLR_ERR 0x20 +#define RNGC_CMD_SEED 0x2 + +#define RNGC_CTRL_AUTO_SEED 0x10 + +#define RNGC_STATUS_ERROR 0x10000 +#define RNGC_STATUS_FIFO_LEVEL_MASK 0xf00 +#define RNGC_STATUS_FIFO_LEVEL_SHIFT 8 +#define RNGC_STATUS_SEED_DONE 0x20 +#define RNGC_STATUS_ST_DONE 0x10 + +#define RNGC_ERROR_STATUS_STAT_ERR 0x8 + +#define RNGC_TIMEOUT 3000000U /* 3 sec */ + +struct imx_rngc_priv { + unsigned long base; +}; + +static int rngc_read(struct udevice *dev, void *data, size_t len) +{ + struct imx_rngc_priv *priv = dev_get_priv(dev); + u8 buffer[DCP_RNG_MAX_FIFO_STORE_SIZE]; + u32 status, level; + size_t size; + + while (len) { + status = readl(priv->base + RNGC_STATUS); + + /* is there some error while reading this random number? */ + if (status & RNGC_STATUS_ERROR) + break; + /* how many random numbers are in FIFO? [0-16] */ + level = (status & RNGC_STATUS_FIFO_LEVEL_MASK) >> + RNGC_STATUS_FIFO_LEVEL_SHIFT; + + if (level) { + /* retrieve a random number from FIFO */ + *(u32 *)buffer = readl(priv->base + RNGC_FIFO); + size = min(len, sizeof(u32)); + memcpy(data, buffer, size); + data += size; + len -= size; + } + } + + return len ? -EIO : 0; +} + +static int rngc_init(struct imx_rngc_priv *priv) +{ + u32 cmd, ctrl, status, err_reg = 0; + unsigned long long timeval = 0; + unsigned long long timeout = RNGC_TIMEOUT; + + /* clear error */ + cmd = readl(priv->base + RNGC_COMMAND); + writel(cmd | RNGC_CMD_CLR_ERR, priv->base + RNGC_COMMAND); + + /* create seed, repeat while there is some statistical error */ + do { + /* seed creation */ + cmd = readl(priv->base + RNGC_COMMAND); + writel(cmd | RNGC_CMD_SEED, priv->base + RNGC_COMMAND); + + udelay(1); + timeval += 1; + + status = readl(priv->base + RNGC_STATUS); + err_reg = readl(priv->base + RNGC_ERROR); + + if (status & (RNGC_STATUS_SEED_DONE | RNGC_STATUS_ST_DONE)) + break; + + if (timeval > timeout) { + debug("rngc timed out\n"); + return -ETIMEDOUT; + } + } while (err_reg == RNGC_ERROR_STATUS_STAT_ERR); + + if (err_reg) + return -EIO; + + /* + * enable automatic seeding, the rngc creates a new seed automatically + * after serving 2^20 random 160-bit words + */ + ctrl = readl(priv->base + RNGC_CONTROL); + ctrl |= RNGC_CTRL_AUTO_SEED; + writel(ctrl, priv->base + RNGC_CONTROL); + return 0; +} + +static int rngc_probe(struct udevice *dev) +{ + struct imx_rngc_priv *priv = dev_get_priv(dev); + fdt_addr_t addr; + u32 ver_id; + u8 rng_type; + int ret; + + addr = dev_read_addr(dev); + if (addr == FDT_ADDR_T_NONE) { + ret = -EINVAL; + goto err; + } + + priv->base = addr; + ver_id = readl(priv->base + RNGC_VER_ID); + rng_type = ver_id >> RNGC_TYPE_SHIFT; + /* + * This driver supports only RNGC and RNGB. (There's a different + * driver for RNGA.) + */ + if (rng_type != RNGC_TYPE_RNGC && rng_type != RNGC_TYPE_RNGB) { + ret = -ENODEV; + goto err; + } + + ret = rngc_init(priv); + if (ret) + goto err; + + return 0; + +err: + printf("%s error = %d\n", __func__, ret); + return ret; +} + +static const struct dm_rng_ops rngc_ops = { + .read = rngc_read, +}; + +static const struct udevice_id rngc_dt_ids[] = { + { .compatible = "fsl,imx25-rngb" }, + { } +}; + +U_BOOT_DRIVER(dcp_rng) = { + .name = "dcp_rng", + .id = UCLASS_RNG, + .of_match = rngc_dt_ids, + .ops = &rngc_ops, + .probe = rngc_probe, + .priv_auto = sizeof(struct imx_rngc_priv), + .flags = DM_FLAG_ALLOC_PRIV_DMA, +};

On Thu, Dec 22, 2022 at 09:50:27AM +0100, Kshitiz Varshney wrote:
This commit introduces Random number generator to uboot. It uses DCP driver for number generation. RNG driver can be invoked by using below command on uboot prompt:- rng <number of bytes>
Signed-off-by: Kshitiz Varshney kshitiz.varshney@nxp.com Reviewed-by: Ye Li ye.li@nxp.com Reviewed-by: Simon Glass sjg@chromium.org
Applied to u-boot/master, thanks!

This commit initializes dcp_rng device driver inside arch_misc_init() function.
Signed-off-by: Kshitiz Varshney kshitiz.varshney@nxp.com Reviewed-by: Ye Li ye.li@nxp.com --- arch/arm/mach-imx/mx6/soc.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/arch/arm/mach-imx/mx6/soc.c b/arch/arm/mach-imx/mx6/soc.c index 08f47cf03d..c2875e727c 100644 --- a/arch/arm/mach-imx/mx6/soc.c +++ b/arch/arm/mach-imx/mx6/soc.c @@ -746,6 +746,16 @@ int arch_misc_init(void) if (ret) printf("Failed to initialize caam_jr: %d\n", ret); } + + if (IS_ENABLED(CONFIG_FSL_DCP_RNG)) { + struct udevice *dev; + int ret; + + ret = uclass_get_device_by_driver(UCLASS_RNG, DM_DRIVER_GET(dcp_rng), &dev); + if (ret) + printf("Failed to initialize dcp rng: %d\n", ret); + } + setup_serial_number(); return 0; }

On Thu, Dec 22, 2022 at 09:50:28AM +0100, Kshitiz Varshney wrote:
This commit initializes dcp_rng device driver inside arch_misc_init() function.
Signed-off-by: Kshitiz Varshney kshitiz.varshney@nxp.com Reviewed-by: Ye Li ye.li@nxp.com
Applied to u-boot/master, thanks!

This commit adds configs required for using dcp_rng driver in imx6ull defconfig files.
Signed-off-by: Kshitiz Varshney kshitiz.varshney@nxp.com Reviewed-by: Ye Li ye.li@nxp.com --- configs/mx6ull_14x14_evk_defconfig | 4 ++++ configs/mx6ull_14x14_evk_plugin_defconfig | 4 ++++ 2 files changed, 8 insertions(+)
diff --git a/configs/mx6ull_14x14_evk_defconfig b/configs/mx6ull_14x14_evk_defconfig index 65db621f15..881bc27a69 100644 --- a/configs/mx6ull_14x14_evk_defconfig +++ b/configs/mx6ull_14x14_evk_defconfig @@ -65,3 +65,7 @@ CONFIG_DM_SPI=y CONFIG_FSL_QSPI=y CONFIG_SOFT_SPI=y CONFIG_IMX_THERMAL=y +CONFIG_ARCH_MISC_INIT=y +CONFIG_DM_RNG=y +CONFIG_CMD_RNG=y +CONFIG_FSL_DCP_RNG=y diff --git a/configs/mx6ull_14x14_evk_plugin_defconfig b/configs/mx6ull_14x14_evk_plugin_defconfig index 55ddd7eabb..5e6766282e 100644 --- a/configs/mx6ull_14x14_evk_plugin_defconfig +++ b/configs/mx6ull_14x14_evk_plugin_defconfig @@ -64,3 +64,7 @@ CONFIG_DM_SPI=y CONFIG_FSL_QSPI=y CONFIG_SOFT_SPI=y CONFIG_IMX_THERMAL=y +CONFIG_ARCH_MISC_INIT=y +CONFIG_DM_RNG=y +CONFIG_CMD_RNG=y +CONFIG_FSL_DCP_RNG=y

On Thu, Dec 22, 2022 at 09:50:29AM +0100, Kshitiz Varshney wrote:
This commit adds configs required for using dcp_rng driver in imx6ull defconfig files.
Signed-off-by: Kshitiz Varshney kshitiz.varshney@nxp.com Reviewed-by: Ye Li ye.li@nxp.com
Applied to u-boot/master, thanks!

On 12/22/22 09:50, Kshitiz Varshney wrote:
Implemented Data Co-Processor random number generation driver.
usage command: rng <number of bytes>
Kshitiz Varshney (3): Uboot RNG Driver using Data Co-processor Added dcp_rng driver initialization code Added configs required for dcp_rng driver
arch/arm/mach-imx/mx6/soc.c | 10 ++ configs/mx6ull_14x14_evk_defconfig | 4 + configs/mx6ull_14x14_evk_plugin_defconfig | 4 +
Do these boards lack the CAAM RNG supported by drivers/crypto/fsl/rng.c?
Best regards
Heinrich
drivers/crypto/fsl/Kconfig | 10 ++ drivers/crypto/fsl/Makefile | 1 + drivers/crypto/fsl/dcp_rng.c | 182 ++++++++++++++++++++++ 6 files changed, 211 insertions(+) create mode 100644 drivers/crypto/fsl/dcp_rng.c

Hi Heinrich,
On Thu, Dec 22, 2022 at 9:52 PM Heinrich Schuchardt xypron.glpk@gmx.de wrote:
configs/mx6ull_14x14_evk_defconfig | 4 + configs/mx6ull_14x14_evk_plugin_defconfig | 4 +
Do these boards lack the CAAM RNG supported by drivers/crypto/fsl/rng.c?
imx6ull does not have CAAM.
participants (4)
-
Fabio Estevam
-
Heinrich Schuchardt
-
Kshitiz Varshney
-
Tom Rini