[PATCH 4/4] crypto/fsl: add RNG support
Michael Walle
michael at walle.cc
Wed Jun 3 00:05:54 CEST 2020
Register the random number generator with the rng subsystem in u-boot.
This way it can be used by EFI as well as for the 'rng' command.
Signed-off-by: Michael Walle <michael at walle.cc>
---
drivers/crypto/fsl/Kconfig | 11 +++++
drivers/crypto/fsl/Makefile | 1 +
drivers/crypto/fsl/jobdesc.c | 9 ++++
drivers/crypto/fsl/jobdesc.h | 3 ++
drivers/crypto/fsl/jr.c | 9 ++++
drivers/crypto/fsl/rng.c | 84 ++++++++++++++++++++++++++++++++++++
6 files changed, 117 insertions(+)
create mode 100644 drivers/crypto/fsl/rng.c
diff --git a/drivers/crypto/fsl/Kconfig b/drivers/crypto/fsl/Kconfig
index 181a1e5e99..5936b77494 100644
--- a/drivers/crypto/fsl/Kconfig
+++ b/drivers/crypto/fsl/Kconfig
@@ -45,3 +45,14 @@ config SYS_FSL_SEC_COMPAT
config SYS_FSL_SEC_LE
bool "Little-endian access to Freescale Secure Boot"
+
+if FSL_CAAM
+
+config FSL_CAAM_RNG
+ bool "Enable Random Number Generator support"
+ depends on DM_RNG
+ default y
+ help
+ Enable support for the random number generator module of the CAAM.
+
+endif
diff --git a/drivers/crypto/fsl/Makefile b/drivers/crypto/fsl/Makefile
index cfb36f3bb9..a5e8d38e38 100644
--- a/drivers/crypto/fsl/Makefile
+++ b/drivers/crypto/fsl/Makefile
@@ -7,3 +7,4 @@ obj-$(CONFIG_FSL_CAAM) += jr.o fsl_hash.o jobdesc.o error.o
obj-$(CONFIG_CMD_BLOB) += fsl_blob.o
obj-$(CONFIG_CMD_DEKBLOB) += fsl_blob.o
obj-$(CONFIG_RSA_FREESCALE_EXP) += fsl_rsa.o
+obj-$(CONFIG_FSL_CAAM_RNG) += rng.o
diff --git a/drivers/crypto/fsl/jobdesc.c b/drivers/crypto/fsl/jobdesc.c
index 2f35e0c90b..5602a3d93c 100644
--- a/drivers/crypto/fsl/jobdesc.c
+++ b/drivers/crypto/fsl/jobdesc.c
@@ -286,6 +286,15 @@ void inline_cnstr_jobdesc_rng_instantiation(uint32_t *desc, int handle)
}
}
+void inline_cnstr_jobdesc_rng(u32 *desc, void *data_out, u32 size)
+{
+ dma_addr_t dma_data_out = virt_to_phys(data_out);
+
+ init_job_desc(desc, 0);
+ append_operation(desc, OP_ALG_ALGSEL_RNG | OP_TYPE_CLASS1_ALG);
+ append_fifo_store(desc, dma_data_out, size, FIFOST_TYPE_RNGSTORE);
+}
+
/* Change key size to bytes form bits in calling function*/
void inline_cnstr_jobdesc_pkha_rsaexp(uint32_t *desc,
struct pk_in_params *pkin, uint8_t *out,
diff --git a/drivers/crypto/fsl/jobdesc.h b/drivers/crypto/fsl/jobdesc.h
index d782c46b9d..35075ff434 100644
--- a/drivers/crypto/fsl/jobdesc.h
+++ b/drivers/crypto/fsl/jobdesc.h
@@ -41,7 +41,10 @@ void inline_cnstr_jobdesc_blob_decap(uint32_t *desc, uint8_t *key_idnfr,
void inline_cnstr_jobdesc_rng_instantiation(uint32_t *desc, int handle);
+void inline_cnstr_jobdesc_rng(u32 *desc, void *data_out, u32 size);
+
void inline_cnstr_jobdesc_pkha_rsaexp(uint32_t *desc,
struct pk_in_params *pkin, uint8_t *out,
uint32_t out_siz);
+
#endif
diff --git a/drivers/crypto/fsl/jr.c b/drivers/crypto/fsl/jr.c
index 9f3da9c474..8ecc0f05b0 100644
--- a/drivers/crypto/fsl/jr.c
+++ b/drivers/crypto/fsl/jr.c
@@ -19,6 +19,7 @@
#include <asm/cache.h>
#include <asm/fsl_pamu.h>
#endif
+#include <dm/lists.h>
#define CIRC_CNT(head, tail, size) (((head) - (tail)) & (size - 1))
#define CIRC_SPACE(head, tail, size) CIRC_CNT((tail), (head) + 1, (size))
@@ -665,6 +666,14 @@ int sec_init_idx(uint8_t sec_idx)
printf("SEC%u: RNG instantiation failed\n", sec_idx);
return -1;
}
+#ifdef CONFIG_DM_RNG
+ if (IS_ENABLED(CONFIG_DM_RNG)) {
+ ret = device_bind_driver(NULL, "caam-rng", "caam-rng",
+ NULL);
+ if (ret)
+ printf("Couldn't bind rng driver (%d)\n", ret);
+ }
+#endif
printf("SEC%u: RNG instantiated\n", sec_idx);
}
#endif
diff --git a/drivers/crypto/fsl/rng.c b/drivers/crypto/fsl/rng.c
new file mode 100644
index 0000000000..3da318d767
--- /dev/null
+++ b/drivers/crypto/fsl/rng.c
@@ -0,0 +1,84 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2020 Michael Walle <michael at walle.cc>
+ *
+ * Driver for Freescale Cryptographic Accelerator and Assurance
+ * Module (CAAM) hardware random number generator.
+ */
+
+#include <asm/cache.h>
+#include <common.h>
+#include <cpu_func.h>
+#include <dm.h>
+#include <rng.h>
+#include "desc_constr.h"
+#include "jobdesc.h"
+#include "jr.h"
+
+#define CAAM_RNG_MAX_FIFO_STORE_SIZE 16
+#define CAAM_RNG_DESC_LEN (3 * CAAM_CMD_SZ + CAAM_PTR_SZ)
+
+struct caam_rng_platdata {
+ u32 desc[CAAM_RNG_DESC_LEN / 4];
+ u8 data[CAAM_RNG_MAX_FIFO_STORE_SIZE] __aligned(ARCH_DMA_MINALIGN);
+};
+
+static int caam_rng_read_one(struct caam_rng_platdata *pdata)
+{
+ int size = CAAM_RNG_MAX_FIFO_STORE_SIZE;
+ int ret;
+
+ ret = run_descriptor_jr(pdata->desc);
+ if (ret < 0)
+ return -EIO;
+
+ invalidate_dcache_range((unsigned long)pdata->data,
+ (unsigned long)pdata->data + size);
+
+ return 0;
+}
+
+static int caam_rng_read(struct udevice *dev, void *data, size_t len)
+{
+ struct caam_rng_platdata *pdata = dev_get_platdata(dev);
+ u8 *buffer = data;
+ size_t size;
+ int ret;
+
+ while (len) {
+ ret = caam_rng_read_one(pdata);
+ if (ret)
+ return ret;
+
+ size = min(len, (size_t)CAAM_RNG_MAX_FIFO_STORE_SIZE);
+
+ memcpy(buffer, pdata->data, len);
+ buffer += size;
+ len -= size;
+ }
+
+ return 0;
+}
+
+static int caam_rng_probe(struct udevice *dev)
+{
+ struct caam_rng_platdata *pdata = dev_get_platdata(dev);
+
+ inline_cnstr_jobdesc_rng(pdata->desc, pdata->data,
+ CAAM_RNG_MAX_FIFO_STORE_SIZE);
+
+ return 0;
+}
+
+static const struct dm_rng_ops caam_rng_ops = {
+ .read = caam_rng_read,
+};
+
+U_BOOT_DRIVER(caam_rng) = {
+ .name = "caam-rng",
+ .id = UCLASS_RNG,
+ .ops = &caam_rng_ops,
+ .probe = caam_rng_probe,
+ .platdata_auto_alloc_size = sizeof(struct caam_rng_platdata),
+ .flags = DM_FLAG_ALLOC_PRIV_DMA,
+};
--
2.20.1
More information about the U-Boot
mailing list