From patchwork Tue Jun 2 22:05:54 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Walle X-Patchwork-Id: 241580 List-Id: U-Boot discussion From: michael at walle.cc (Michael Walle) Date: Wed, 3 Jun 2020 00:05:54 +0200 Subject: [PATCH 4/4] crypto/fsl: add RNG support In-Reply-To: <20200602220554.22477-1-michael@walle.cc> References: <20200602220554.22477-1-michael@walle.cc> Message-ID: <20200602220554.22477-5-michael@walle.cc> 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 --- 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 #include #endif +#include #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 + * + * Driver for Freescale Cryptographic Accelerator and Assurance + * Module (CAAM) hardware random number generator. + */ + +#include +#include +#include +#include +#include +#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, +};