From patchwork Tue Jun 2 22:05:51 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Walle X-Patchwork-Id: 241583 List-Id: U-Boot discussion From: michael at walle.cc (Michael Walle) Date: Wed, 3 Jun 2020 00:05:51 +0200 Subject: [PATCH 1/4] crypto/fsl: make SEC%u status line consistent In-Reply-To: <20200602220554.22477-1-michael@walle.cc> References: <20200602220554.22477-1-michael@walle.cc> Message-ID: <20200602220554.22477-2-michael@walle.cc> Align the status line with all the other output in U-Boot. Before the change: DDR 3.9 GiB (DDR3, 32-bit, CL=11, ECC on) SEC0: RNG instantiated WDT: Started with servicing (60s timeout) After the change: DDR 3.9 GiB (DDR3, 32-bit, CL=11, ECC on) SEC0: RNG instantiated WDT: Started with servicing (60s timeout) Signed-off-by: Michael Walle --- drivers/crypto/fsl/jr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/crypto/fsl/jr.c b/drivers/crypto/fsl/jr.c index e2d9216cfc..612e86818b 100644 --- a/drivers/crypto/fsl/jr.c +++ b/drivers/crypto/fsl/jr.c @@ -657,7 +657,7 @@ int sec_init_idx(uint8_t sec_idx) printf("SEC%u: RNG instantiation failed\n", sec_idx); return -1; } - printf("SEC%u: RNG instantiated\n", sec_idx); + printf("SEC%u: RNG instantiated\n", sec_idx); } #endif return ret; From patchwork Tue Jun 2 22:05:52 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Walle X-Patchwork-Id: 241579 List-Id: U-Boot discussion From: michael at walle.cc (Michael Walle) Date: Wed, 3 Jun 2020 00:05:52 +0200 Subject: [PATCH 2/4] crypto/fsl: export caam_get_era() In-Reply-To: <20200602220554.22477-1-michael@walle.cc> References: <20200602220554.22477-1-michael@walle.cc> Message-ID: <20200602220554.22477-3-michael@walle.cc> We need the era in other modules, too. For example, to get the RNG version. Signed-off-by: Michael Walle Reviewed-by: Horia Geant? --- drivers/crypto/fsl/sec.c | 2 +- include/fsl_sec.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/crypto/fsl/sec.c b/drivers/crypto/fsl/sec.c index a2c0bfaf44..a2fe5b1cc9 100644 --- a/drivers/crypto/fsl/sec.c +++ b/drivers/crypto/fsl/sec.c @@ -98,7 +98,7 @@ void fdt_fixup_crypto_node(void *blob, int sec_rev) fdt_strerror(err)); } #elif CONFIG_SYS_FSL_SEC_COMPAT >= 4 /* SEC4 */ -static u8 caam_get_era(void) +u8 caam_get_era(void) { static const struct { u16 ip_id; diff --git a/include/fsl_sec.h b/include/fsl_sec.h index c0d2c7e866..2ebb75c9b2 100644 --- a/include/fsl_sec.h +++ b/include/fsl_sec.h @@ -316,6 +316,8 @@ int blob_dek(const u8 *src, u8 *dst, u8 len); int sec_init_idx(uint8_t); #endif int sec_init(void); + +u8 caam_get_era(void); #endif #endif /* __FSL_SEC_H */ From patchwork Tue Jun 2 22:05:53 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Walle X-Patchwork-Id: 241582 List-Id: U-Boot discussion From: michael at walle.cc (Michael Walle) Date: Wed, 3 Jun 2020 00:05:53 +0200 Subject: [PATCH 3/4] crypto/fsl: support newer SEC modules In-Reply-To: <20200602220554.22477-1-michael@walle.cc> References: <20200602220554.22477-1-michael@walle.cc> Message-ID: <20200602220554.22477-4-michael@walle.cc> Since Era 10, the version registers changed. Add the version registers and use them on newer modules. Signed-off-by: Michael Walle Reviewed-by: Horia Geant? --- drivers/crypto/fsl/jr.c | 12 ++++++++-- include/fsl_sec.h | 51 +++++++++++++++++++++++++++++++++++------ 2 files changed, 54 insertions(+), 9 deletions(-) diff --git a/drivers/crypto/fsl/jr.c b/drivers/crypto/fsl/jr.c index 612e86818b..9f3da9c474 100644 --- a/drivers/crypto/fsl/jr.c +++ b/drivers/crypto/fsl/jr.c @@ -498,9 +498,17 @@ static int instantiate_rng(uint8_t sec_idx) static u8 get_rng_vid(uint8_t sec_idx) { ccsr_sec_t *sec = (void *)SEC_ADDR(sec_idx); - u32 cha_vid = sec_in32(&sec->chavid_ls); + u8 vid; - return (cha_vid & SEC_CHAVID_RNG_LS_MASK) >> SEC_CHAVID_LS_RNG_SHIFT; + if (caam_get_era() < 10) { + vid = (sec_in32(&sec->chavid_ls) & SEC_CHAVID_RNG_LS_MASK) + >> SEC_CHAVID_LS_RNG_SHIFT; + } else { + vid = (sec_in32(&sec->vreg.rng) & CHA_VER_VID_MASK) + >> CHA_VER_VID_SHIFT; + } + + return vid; } /* diff --git a/include/fsl_sec.h b/include/fsl_sec.h index 2ebb75c9b2..8dce0bbb1b 100644 --- a/include/fsl_sec.h +++ b/include/fsl_sec.h @@ -73,6 +73,41 @@ struct rng4tst { u32 rsvd2[15]; }; +/* Version registers (Era 10+) */ +struct version_regs { + u32 crca; /* CRCA_VERSION */ + u32 afha; /* AFHA_VERSION */ + u32 kfha; /* KFHA_VERSION */ + u32 pkha; /* PKHA_VERSION */ + u32 aesa; /* AESA_VERSION */ + u32 mdha; /* MDHA_VERSION */ + u32 desa; /* DESA_VERSION */ + u32 snw8a; /* SNW8A_VERSION */ + u32 snw9a; /* SNW9A_VERSION */ + u32 zuce; /* ZUCE_VERSION */ + u32 zuca; /* ZUCA_VERSION */ + u32 ccha; /* CCHA_VERSION */ + u32 ptha; /* PTHA_VERSION */ + u32 rng; /* RNG_VERSION */ + u32 trng; /* TRNG_VERSION */ + u32 aaha; /* AAHA_VERSION */ + u32 rsvd[10]; + u32 sr; /* SR_VERSION */ + u32 dma; /* DMA_VERSION */ + u32 ai; /* AI_VERSION */ + u32 qi; /* QI_VERSION */ + u32 jr; /* JR_VERSION */ + u32 deco; /* DECO_VERSION */ +}; + +#define CHA_VER_NUM_MASK 0x000000ff +#define CHA_VER_MISC_SHIFT 8 +#define CHA_VER_MISC_MASK 0x0000ff00 +#define CHA_VER_REV_SHIFT 16 +#define CHA_VER_REV_MASK 0x00ff0000 +#define CHA_VER_VID_SHIFT 24 +#define CHA_VER_VID_MASK 0xff000000 + typedef struct ccsr_sec { u32 res0; u32 mcfgr; /* Master CFG Register */ @@ -98,17 +133,19 @@ typedef struct ccsr_sec { u32 drr; /* DECO Reset Register */ u8 res5[0x4d8]; struct rng4tst rng; /* RNG Registers */ - u8 res6[0x8a0]; + u8 res6[0x780]; + struct version_regs vreg; /* version registers since era 10 */ + u8 res7[0xa0]; u32 crnr_ms; /* CHA Revision Number Register, MS */ u32 crnr_ls; /* CHA Revision Number Register, LS */ u32 ctpr_ms; /* Compile Time Parameters Register, MS */ u32 ctpr_ls; /* Compile Time Parameters Register, LS */ - u8 res7[0x10]; + u8 res8[0x10]; u32 far_ms; /* Fault Address Register, MS */ u32 far_ls; /* Fault Address Register, LS */ u32 falr; /* Fault Address LIODN Register */ u32 fadr; /* Fault Address Detail Register */ - u8 res8[0x4]; + u8 res9[0x4]; u32 csta; /* CAAM Status Register */ u32 smpart; /* Secure Memory Partition Parameters */ u32 smvid; /* Secure Memory Version ID */ @@ -121,16 +158,16 @@ typedef struct ccsr_sec { u32 secvid_ms; /* SEC Version ID Register, MS */ u32 secvid_ls; /* SEC Version ID Register, LS */ #if defined(CONFIG_FSL_LSCH2) || defined(CONFIG_FSL_LSCH3) - u8 res9[0x6f020]; + u8 res10[0x6f020]; #else - u8 res9[0x6020]; + u8 res10[0x6020]; #endif u32 qilcr_ms; /* Queue Interface LIODN CFG Register, MS */ u32 qilcr_ls; /* Queue Interface LIODN CFG Register, LS */ #if defined(CONFIG_FSL_LSCH2) || defined(CONFIG_FSL_LSCH3) - u8 res10[0x8ffd8]; + u8 res11[0x8ffd8]; #else - u8 res10[0x8fd8]; + u8 res11[0x8fd8]; #endif } ccsr_sec_t; 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, +};