crypto/fsl: add RNG support
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@walle.cc> Tested-by: Heinrich Schuchardt <xypron.glpk@gmx.de> Reviewed-by: Priyanka Jain <priyanka.jain@nxp.com>
This commit is contained in:
		
							parent
							
								
									b980f9e259
								
							
						
					
					
						commit
						ea95f2142e
					
				|  | @ -45,3 +45,17 @@ 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 hardware based random number generator | ||||
| 	  module of the CAAM. The random data is fetched from the DRGB | ||||
| 	  using the prediction resistance flag which means the DRGB is | ||||
| 	  reseeded from the TRNG every time random data is generated. | ||||
| 
 | ||||
| endif | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -296,6 +296,16 @@ void inline_cnstr_jobdesc_rng_deinstantiation(u32 *desc, int handle) | |||
| 			 (handle << OP_ALG_AAI_SHIFT) | OP_ALG_AS_INITFINAL); | ||||
| } | ||||
| 
 | ||||
| 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 | | ||||
| 			 OP_ALG_PR_ON); | ||||
| 	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, | ||||
|  |  | |||
|  | @ -43,7 +43,10 @@ void inline_cnstr_jobdesc_rng_instantiation(u32 *desc, int handle, int do_sk); | |||
| 
 | ||||
| void inline_cnstr_jobdesc_rng_deinstantiation(u32 *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 | ||||
|  |  | |||
|  | @ -20,6 +20,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)) | ||||
|  | @ -721,6 +722,14 @@ int sec_init_idx(uint8_t sec_idx) | |||
| 			printf("SEC%u:  RNG instantiation failed\n", sec_idx); | ||||
| 			return -1; | ||||
| 		} | ||||
| 
 | ||||
| 		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); | ||||
| 		} | ||||
| 
 | ||||
| 		printf("SEC%u:  RNG instantiated\n", sec_idx); | ||||
| 	} | ||||
| #endif | ||||
|  |  | |||
|  | @ -0,0 +1,88 @@ | |||
| // SPDX-License-Identifier: GPL-2.0-or-later
 | ||||
| /*
 | ||||
|  * Copyright (c) 2020 Michael Walle <michael@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 <linux/kernel.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_priv { | ||||
| 	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_priv *priv) | ||||
| { | ||||
| 	int size = ALIGN(CAAM_RNG_MAX_FIFO_STORE_SIZE, ARCH_DMA_MINALIGN); | ||||
| 	int ret; | ||||
| 
 | ||||
| 	ret = run_descriptor_jr(priv->desc); | ||||
| 	if (ret < 0) | ||||
| 		return -EIO; | ||||
| 
 | ||||
| 	invalidate_dcache_range((unsigned long)priv->data, | ||||
| 				(unsigned long)priv->data + size); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int caam_rng_read(struct udevice *dev, void *data, size_t len) | ||||
| { | ||||
| 	struct caam_rng_priv *priv = dev_get_priv(dev); | ||||
| 	u8 *buffer = data; | ||||
| 	size_t size; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	while (len) { | ||||
| 		ret = caam_rng_read_one(priv); | ||||
| 		if (ret) | ||||
| 			return ret; | ||||
| 
 | ||||
| 		size = min(len, (size_t)CAAM_RNG_MAX_FIFO_STORE_SIZE); | ||||
| 
 | ||||
| 		memcpy(buffer, priv->data, size); | ||||
| 		buffer += size; | ||||
| 		len -= size; | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int caam_rng_probe(struct udevice *dev) | ||||
| { | ||||
| 	struct caam_rng_priv *priv = dev_get_priv(dev); | ||||
| 	ulong size = ALIGN(CAAM_RNG_DESC_LEN, ARCH_DMA_MINALIGN); | ||||
| 
 | ||||
| 	inline_cnstr_jobdesc_rng(priv->desc, priv->data, | ||||
| 				 CAAM_RNG_MAX_FIFO_STORE_SIZE); | ||||
| 	flush_dcache_range((unsigned long)priv->desc, | ||||
| 			   (unsigned long)priv->desc + 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, | ||||
| 	.priv_auto_alloc_size = sizeof(struct caam_rng_priv), | ||||
| 	.flags = DM_FLAG_ALLOC_PRIV_DMA, | ||||
| }; | ||||
		Loading…
	
		Reference in New Issue