xref: /optee_os/core/drivers/crypto/caam/caam_rng.c (revision ba7db6e014eceb116bf6f8cebc7d3d2eb149c7d6)
12d7a8964SCedric Neveux // SPDX-License-Identifier: BSD-2-Clause
22d7a8964SCedric Neveux /**
3cbb7d5e5SSahil Malhotra  * Copyright 2017-2021, 2024 NXP
42d7a8964SCedric Neveux  *
52d7a8964SCedric Neveux  * Brief   CAAM Random Number Generator manager.
62d7a8964SCedric Neveux  *         Implementation of RNG functions.
72d7a8964SCedric Neveux  */
82d7a8964SCedric Neveux #include <atomic.h>
92d7a8964SCedric Neveux #include <caam_common.h>
102d7a8964SCedric Neveux #include <caam_hal_rng.h>
112d7a8964SCedric Neveux #include <caam_jr.h>
122d7a8964SCedric Neveux #include <caam_rng.h>
132d7a8964SCedric Neveux #include <caam_utils_mem.h>
14cbb7d5e5SSahil Malhotra #include <caam_utils_status.h>
152d7a8964SCedric Neveux #include <crypto/crypto.h>
162d7a8964SCedric Neveux #include <kernel/panic.h>
172d7a8964SCedric Neveux #include <mm/core_memprot.h>
182d7a8964SCedric Neveux #include <rng_support.h>
192d7a8964SCedric Neveux #include <tee/cache.h>
20b4814b22SJorge Ramirez-Ortiz #include <tee/tee_cryp_utl.h>
212d7a8964SCedric Neveux #include <string.h>
222d7a8964SCedric Neveux 
232d7a8964SCedric Neveux /*
242d7a8964SCedric Neveux  * Define the number of descriptor entry to generate random data
252d7a8964SCedric Neveux  */
262d7a8964SCedric Neveux #define RNG_GEN_DESC_ENTRIES	5
272d7a8964SCedric Neveux 
282d7a8964SCedric Neveux /*
292d7a8964SCedric Neveux  * RNG module private data
302d7a8964SCedric Neveux  */
312d7a8964SCedric Neveux struct rng_privdata {
322d7a8964SCedric Neveux 	vaddr_t baseaddr;                       /* RNG base address */
332d7a8964SCedric Neveux 	bool instantiated;                      /* RNG instantiated */
34ff103169SAhmad Fatoum 	bool pr_enabled;			/* RNG prediction resistance */
352d7a8964SCedric Neveux };
362d7a8964SCedric Neveux 
372d7a8964SCedric Neveux static struct rng_privdata *rng_privdata;
382d7a8964SCedric Neveux 
392d7a8964SCedric Neveux /* Allocate and initialize module private data */
do_allocate(void)402d7a8964SCedric Neveux static enum caam_status do_allocate(void)
412d7a8964SCedric Neveux {
422d7a8964SCedric Neveux 	/* Allocate the Module resources */
432d7a8964SCedric Neveux 	rng_privdata = caam_calloc(sizeof(*rng_privdata));
442d7a8964SCedric Neveux 	if (!rng_privdata) {
452d7a8964SCedric Neveux 		RNG_TRACE("Private Data allocation error");
462d7a8964SCedric Neveux 		return CAAM_OUT_MEMORY;
472d7a8964SCedric Neveux 	}
482d7a8964SCedric Neveux 
492d7a8964SCedric Neveux 	rng_privdata->instantiated = false;
502d7a8964SCedric Neveux 
512d7a8964SCedric Neveux 	return CAAM_NO_ERROR;
522d7a8964SCedric Neveux }
532d7a8964SCedric Neveux 
542d7a8964SCedric Neveux /* Free module private data */
do_free(void)552d7a8964SCedric Neveux static void do_free(void)
562d7a8964SCedric Neveux {
572d7a8964SCedric Neveux 	caam_free(rng_privdata);
582d7a8964SCedric Neveux 	rng_privdata = NULL;
592d7a8964SCedric Neveux }
602d7a8964SCedric Neveux 
612d7a8964SCedric Neveux #ifdef CFG_NXP_CAAM_RNG_DRV
622d7a8964SCedric Neveux /*
632d7a8964SCedric Neveux  * Return the requested random data
642d7a8964SCedric Neveux  *
652d7a8964SCedric Neveux  * @buf  [out] data buffer
662d7a8964SCedric Neveux  * @len  number of bytes to returns
672d7a8964SCedric Neveux  */
do_rng_read(uint8_t * buf,size_t len)682d7a8964SCedric Neveux static TEE_Result do_rng_read(uint8_t *buf, size_t len)
692d7a8964SCedric Neveux {
70cbb7d5e5SSahil Malhotra 	TEE_Result ret = TEE_ERROR_GENERIC;
71cbb7d5e5SSahil Malhotra 	uint32_t *desc = NULL;
72cbb7d5e5SSahil Malhotra 	uint32_t op = RNG_GEN_DATA;
73cbb7d5e5SSahil Malhotra 	void *rng_data = NULL;
74cbb7d5e5SSahil Malhotra 	paddr_t paddr = 0;
75cbb7d5e5SSahil Malhotra 	struct caam_jobctx jobctx = { };
762d7a8964SCedric Neveux 
772d7a8964SCedric Neveux 	if (!rng_privdata) {
782d7a8964SCedric Neveux 		RNG_TRACE("RNG Driver not initialized");
792d7a8964SCedric Neveux 		return TEE_ERROR_BAD_STATE;
802d7a8964SCedric Neveux 	}
812d7a8964SCedric Neveux 
822d7a8964SCedric Neveux 	if (!rng_privdata->instantiated) {
832d7a8964SCedric Neveux 		RNG_TRACE("RNG Driver not initialized");
842d7a8964SCedric Neveux 		return TEE_ERROR_BAD_STATE;
852d7a8964SCedric Neveux 	}
862d7a8964SCedric Neveux 
87cbb7d5e5SSahil Malhotra 	rng_data = caam_calloc_align(len);
88cbb7d5e5SSahil Malhotra 	if (!rng_data) {
89cbb7d5e5SSahil Malhotra 		RNG_TRACE("RNG buffer allocation failed");
90cbb7d5e5SSahil Malhotra 		return TEE_ERROR_OUT_OF_MEMORY;
912d7a8964SCedric Neveux 	}
922d7a8964SCedric Neveux 
93cbb7d5e5SSahil Malhotra 	/* Ensure that data buffer is visible from the HW */
94cbb7d5e5SSahil Malhotra 	cache_operation(TEE_CACHEFLUSH, rng_data, len);
952d7a8964SCedric Neveux 
96cbb7d5e5SSahil Malhotra 	/* Convert the buffer virtual address to physical address */
97cbb7d5e5SSahil Malhotra 	paddr = virt_to_phys(rng_data);
98cbb7d5e5SSahil Malhotra 	if (!paddr) {
99cbb7d5e5SSahil Malhotra 		RNG_TRACE("Virtual/Physical conversion failed");
100cbb7d5e5SSahil Malhotra 		goto exit;
101cbb7d5e5SSahil Malhotra 	}
1022d7a8964SCedric Neveux 
103cbb7d5e5SSahil Malhotra 	desc = caam_calloc_desc(RNG_GEN_DESC_ENTRIES);
104cbb7d5e5SSahil Malhotra 	if (!desc) {
105cbb7d5e5SSahil Malhotra 		RNG_TRACE("Descriptor allocation failed");
106cbb7d5e5SSahil Malhotra 		ret = TEE_ERROR_OUT_OF_MEMORY;
107cbb7d5e5SSahil Malhotra 		goto exit;
108cbb7d5e5SSahil Malhotra 	}
109cbb7d5e5SSahil Malhotra 
110*ba7db6e0SSahil Malhotra 	if (IS_ENABLED(CFG_CAAM_RNG_RUNTIME_PR) && rng_privdata->pr_enabled)
111cbb7d5e5SSahil Malhotra 		op |= ALGO_RNG_PR;
112cbb7d5e5SSahil Malhotra 
113cbb7d5e5SSahil Malhotra 	caam_desc_init(desc);
114cbb7d5e5SSahil Malhotra 	caam_desc_add_word(desc, DESC_HEADER(0));
115cbb7d5e5SSahil Malhotra 	caam_desc_add_word(desc, op);
116cbb7d5e5SSahil Malhotra 	caam_desc_add_word(desc, FIFO_ST(CLASS_NO, RNG_TO_MEM, len));
117cbb7d5e5SSahil Malhotra 	caam_desc_add_ptr(desc, paddr);
118cbb7d5e5SSahil Malhotra 
119cbb7d5e5SSahil Malhotra 	jobctx.desc = desc;
120cbb7d5e5SSahil Malhotra 	RNG_DUMPDESC(desc);
121cbb7d5e5SSahil Malhotra 
122cbb7d5e5SSahil Malhotra 	if (!caam_jr_enqueue(&jobctx, NULL)) {
123cbb7d5e5SSahil Malhotra 		cache_operation(TEE_CACHEINVALIDATE, rng_data, len);
124cbb7d5e5SSahil Malhotra 		memcpy(buf, rng_data, len);
125cbb7d5e5SSahil Malhotra 		ret = TEE_SUCCESS;
1262d7a8964SCedric Neveux 	} else {
127cbb7d5e5SSahil Malhotra 		RNG_TRACE("CAAM Status 0x%08" PRIx32, jobctx.status);
128cbb7d5e5SSahil Malhotra 		ret = job_status_to_tee_result(jobctx.status);
1292d7a8964SCedric Neveux 	}
1302d7a8964SCedric Neveux 
131cbb7d5e5SSahil Malhotra exit:
132cbb7d5e5SSahil Malhotra 	caam_free(rng_data);
133cbb7d5e5SSahil Malhotra 	caam_free_desc(&desc);
134cbb7d5e5SSahil Malhotra 	return ret;
1352d7a8964SCedric Neveux }
1362d7a8964SCedric Neveux #endif /* CFG_NXP_CAAM_RNG_DRV */
1372d7a8964SCedric Neveux 
1382d7a8964SCedric Neveux /*
1392d7a8964SCedric Neveux  * Prepares the instantiation descriptor
1402d7a8964SCedric Neveux  *
1412d7a8964SCedric Neveux  * @nb_sh      Number of the State Handle
1422d7a8964SCedric Neveux  * @sh_status  State Handles status
1432d7a8964SCedric Neveux  * @desc       Reference to the descriptor
1442d7a8964SCedric Neveux  * @desc       [out] Descriptor filled
1452d7a8964SCedric Neveux  */
prepare_inst_desc(uint32_t nb_sh,uint32_t sh_status,uint32_t * desc)1462d7a8964SCedric Neveux static void prepare_inst_desc(uint32_t nb_sh, uint32_t sh_status,
1472d7a8964SCedric Neveux 			      uint32_t *desc)
1482d7a8964SCedric Neveux {
1492d7a8964SCedric Neveux 	bool key_loaded = false;
1502d7a8964SCedric Neveux 	unsigned int sh_idx = 0;
1512d7a8964SCedric Neveux 	unsigned int nb_max_sh = nb_sh;
1522d7a8964SCedric Neveux 
1532d7a8964SCedric Neveux 	/* Read the SH and secure key status */
1542d7a8964SCedric Neveux 	key_loaded = caam_hal_rng_key_loaded(rng_privdata->baseaddr);
1552d7a8964SCedric Neveux 	RNG_TRACE("RNG SH Status 0x%08" PRIx32 " - Key Status %" PRId8,
1562d7a8964SCedric Neveux 		  sh_status, key_loaded);
1572d7a8964SCedric Neveux 
1582d7a8964SCedric Neveux 	while (sh_status & BIT(sh_idx))
1592d7a8964SCedric Neveux 		sh_idx++;
1602d7a8964SCedric Neveux 
1612d7a8964SCedric Neveux 	RNG_TRACE("Instantiation start at SH%" PRIu32 " (%" PRIu32 ")", sh_idx,
1622d7a8964SCedric Neveux 		  nb_max_sh);
1632d7a8964SCedric Neveux 
1642d7a8964SCedric Neveux 	/* Don't set the descriptor header now */
1652d7a8964SCedric Neveux 	caam_desc_init(desc);
1662d7a8964SCedric Neveux 	caam_desc_add_word(desc, DESC_HEADER(0));
1672d7a8964SCedric Neveux 	/* First State Handle to instantiate */
1682d7a8964SCedric Neveux 	caam_desc_add_word(desc, RNG_SH_INST(sh_idx));
1692d7a8964SCedric Neveux 
1702d7a8964SCedric Neveux 	/* Next State Handles */
1712d7a8964SCedric Neveux 	for (sh_idx++; sh_idx < nb_max_sh; sh_idx++) {
1722d7a8964SCedric Neveux 		if (!(sh_status & BIT(sh_idx))) {
1732d7a8964SCedric Neveux 			/*
1742d7a8964SCedric Neveux 			 * If there is more SH to instantiate, add a wait loop
1752d7a8964SCedric Neveux 			 * followed by a reset of the done status to execute
1762d7a8964SCedric Neveux 			 * next command
1772d7a8964SCedric Neveux 			 */
1782d7a8964SCedric Neveux 			caam_desc_add_word(desc,
1792d7a8964SCedric Neveux 					   JUMP_C1_LOCAL(ALL_COND_TRUE,
1802d7a8964SCedric Neveux 							 JMP_COND(NONE), 1));
1812d7a8964SCedric Neveux 			caam_desc_add_word(desc,
1822d7a8964SCedric Neveux 					   LD_NOCLASS_IMM(REG_CLEAR_WRITTEN,
1832d7a8964SCedric Neveux 							  sizeof(uint32_t)));
1842d7a8964SCedric Neveux 			caam_desc_add_word(desc, 0x1);
1852d7a8964SCedric Neveux 			caam_desc_add_word(desc, RNG_SH_INST(sh_idx));
1862d7a8964SCedric Neveux 		}
1872d7a8964SCedric Neveux 	}
1882d7a8964SCedric Neveux 
1892d7a8964SCedric Neveux 	/* Load the Key if needed */
1902d7a8964SCedric Neveux 	if (!key_loaded) {
1912d7a8964SCedric Neveux 		/*
1922d7a8964SCedric Neveux 		 * Add a wait loop while previous operation not completed,
1932d7a8964SCedric Neveux 		 * followed by a register clear before executing next command
1942d7a8964SCedric Neveux 		 */
1952d7a8964SCedric Neveux 		caam_desc_add_word(desc, JUMP_C1_LOCAL(ALL_COND_TRUE,
1962d7a8964SCedric Neveux 						       JMP_COND(NONE), 1));
1972d7a8964SCedric Neveux 		caam_desc_add_word(desc, LD_NOCLASS_IMM(REG_CLEAR_WRITTEN,
1982d7a8964SCedric Neveux 							sizeof(uint32_t)));
1992d7a8964SCedric Neveux 		caam_desc_add_word(desc, 0x1);
2002d7a8964SCedric Neveux 		caam_desc_add_word(desc, RNG_GEN_SECKEYS);
2012d7a8964SCedric Neveux 	}
2022d7a8964SCedric Neveux 
2032d7a8964SCedric Neveux 	RNG_DUMPDESC(desc);
2042d7a8964SCedric Neveux }
2052d7a8964SCedric Neveux 
caam_rng_instantiation(void)2062d7a8964SCedric Neveux enum caam_status caam_rng_instantiation(void)
2072d7a8964SCedric Neveux {
2082d7a8964SCedric Neveux 	enum caam_status retstatus = CAAM_FAILURE;
2092d7a8964SCedric Neveux 	struct caam_jobctx jobctx = {};
2102d7a8964SCedric Neveux 	uint32_t *desc = NULL;
2112d7a8964SCedric Neveux 	uint32_t sh_status = 0;
2122d7a8964SCedric Neveux 	uint32_t nb_sh = 0;
2132d7a8964SCedric Neveux 	uint32_t sh_mask = 0;
2142d7a8964SCedric Neveux 	uint32_t inc_delay = 0;
2152d7a8964SCedric Neveux 
2162d7a8964SCedric Neveux 	RNG_TRACE("RNG Instantation");
2172d7a8964SCedric Neveux 
2182d7a8964SCedric Neveux 	/* Check if RNG is already instantiated */
2191c79614eSClement Faure 	retstatus = caam_hal_rng_instantiated(rng_privdata->baseaddr);
2201c79614eSClement Faure 
2211c79614eSClement Faure 	/* RNG is already instantiated or an error occurred */
2221c79614eSClement Faure 	if (retstatus != CAAM_NOT_INIT)
2232d7a8964SCedric Neveux 		goto end_inst;
2242d7a8964SCedric Neveux 
2252d7a8964SCedric Neveux 	/*
2262d7a8964SCedric Neveux 	 * RNG needs to be instantiated. Allocate and prepare the
2272d7a8964SCedric Neveux 	 * Job Descriptor
2282d7a8964SCedric Neveux 	 */
2292d7a8964SCedric Neveux 
2302d7a8964SCedric Neveux 	/* Calculate the State Handles bit mask */
2312d7a8964SCedric Neveux 	nb_sh = caam_hal_rng_get_nb_sh(rng_privdata->baseaddr);
2322d7a8964SCedric Neveux 	sh_mask = GENMASK_32(nb_sh - 1, 0);
2332d7a8964SCedric Neveux 
2342d7a8964SCedric Neveux 	/*
2352d7a8964SCedric Neveux 	 * The maximum size of the descriptor is:
2362d7a8964SCedric Neveux 	 *    |----------------------|
2372d7a8964SCedric Neveux 	 *    | Header               | = 1
2382d7a8964SCedric Neveux 	 *    |----------------------|
2392d7a8964SCedric Neveux 	 *    | First instantation   | = 1
2402d7a8964SCedric Neveux 	 *    |----------------------|-------------------------
2412d7a8964SCedric Neveux 	 *    | wait complete        | = 1
2422d7a8964SCedric Neveux 	 *    |----------------------|
2432d7a8964SCedric Neveux 	 *    | Clear done status    |       Repeat (nb_sh - 1)
2442d7a8964SCedric Neveux 	 *    |                      | = 2
2452d7a8964SCedric Neveux 	 *    |----------------------|
2462d7a8964SCedric Neveux 	 *    | next SH instantation | = 1
2472d7a8964SCedric Neveux 	 *    |----------------------|-------------------------
2482d7a8964SCedric Neveux 	 *    | wait complete        | = 1
2492d7a8964SCedric Neveux 	 *    |----------------------|
2502d7a8964SCedric Neveux 	 *    | Clear done status    | = 2
2512d7a8964SCedric Neveux 	 *    |                      |
2522d7a8964SCedric Neveux 	 *    |----------------------|
2532d7a8964SCedric Neveux 	 *    | Generate Secure Keys | = 1
2542d7a8964SCedric Neveux 	 *    |----------------------|
2552d7a8964SCedric Neveux 	 *    | Pad with a 0         | = 1
2562d7a8964SCedric Neveux 	 */
2572d7a8964SCedric Neveux 	desc = caam_calloc_desc(2 + (nb_sh - 1) * 4 + 4 + 1);
2582d7a8964SCedric Neveux 	if (!desc) {
2592d7a8964SCedric Neveux 		RNG_TRACE("Descriptor Allocation error");
2602d7a8964SCedric Neveux 		retstatus = CAAM_OUT_MEMORY;
2612d7a8964SCedric Neveux 		goto end_inst;
2622d7a8964SCedric Neveux 	}
2632d7a8964SCedric Neveux 
2642d7a8964SCedric Neveux 	jobctx.desc = desc;
2652d7a8964SCedric Neveux 
2662d7a8964SCedric Neveux 	do {
2672d7a8964SCedric Neveux 		/* Check if all State Handles are instantiated */
2682d7a8964SCedric Neveux 		sh_status = caam_hal_rng_get_sh_status(rng_privdata->baseaddr);
2692d7a8964SCedric Neveux 		if ((sh_status & sh_mask) == sh_mask) {
2702d7a8964SCedric Neveux 			RNG_TRACE("RNG All SH are instantiated (0x%08" PRIx32
2712d7a8964SCedric Neveux 				  ")",
2722d7a8964SCedric Neveux 				  sh_status);
2732d7a8964SCedric Neveux 			retstatus = CAAM_NO_ERROR;
2742d7a8964SCedric Neveux 			goto end_inst;
2752d7a8964SCedric Neveux 		}
2762d7a8964SCedric Neveux 
2772d7a8964SCedric Neveux 		if (sh_status == 0) {
2782d7a8964SCedric Neveux 			retstatus = caam_hal_rng_kick(rng_privdata->baseaddr,
2792d7a8964SCedric Neveux 						      inc_delay);
2802d7a8964SCedric Neveux 			RNG_TRACE("RNG Kick (inc=%" PRIu32 ") ret 0x%08x",
2812d7a8964SCedric Neveux 				  inc_delay, retstatus);
2822d7a8964SCedric Neveux 			if (retstatus != CAAM_NO_ERROR) {
2832d7a8964SCedric Neveux 				retstatus = CAAM_FAILURE;
2842d7a8964SCedric Neveux 				goto end_inst;
2852d7a8964SCedric Neveux 			}
2862d7a8964SCedric Neveux 			inc_delay += 200;
2872d7a8964SCedric Neveux 		}
2882d7a8964SCedric Neveux 
2892d7a8964SCedric Neveux 		prepare_inst_desc(nb_sh, sh_status, desc);
2902d7a8964SCedric Neveux 
2912d7a8964SCedric Neveux 		retstatus = caam_jr_enqueue(&jobctx, NULL);
2922d7a8964SCedric Neveux 		RNG_TRACE("RNG Job returned 0x%08x", retstatus);
2932d7a8964SCedric Neveux 
2942d7a8964SCedric Neveux 		if (retstatus != CAAM_NO_ERROR &&
2952d7a8964SCedric Neveux 		    retstatus != CAAM_JOB_STATUS)
2962d7a8964SCedric Neveux 			goto end_inst;
2972d7a8964SCedric Neveux 
2982d7a8964SCedric Neveux 		if (retstatus == CAAM_JOB_STATUS) {
2992d7a8964SCedric Neveux 			RNG_TRACE("RNG Job status 0x%08" PRIx32, jobctx.status);
3002d7a8964SCedric Neveux 			if ((JRSTA_SRC_GET(jobctx.status) != JRSTA_SRC(CCB)) ||
3012d7a8964SCedric Neveux 			    (JRSTA_CCB_GET_ERR(jobctx.status) !=
3022d7a8964SCedric Neveux 			     (JRSTA_CCB_CHAID_RNG | JRSTA_CCB_ERRID_HW)))
3032d7a8964SCedric Neveux 				retstatus = CAAM_FAILURE;
3042d7a8964SCedric Neveux 			else
3052d7a8964SCedric Neveux 				retstatus = CAAM_NO_ERROR;
3062d7a8964SCedric Neveux 		}
3072d7a8964SCedric Neveux 	} while (retstatus == CAAM_NO_ERROR);
3082d7a8964SCedric Neveux 
3092d7a8964SCedric Neveux end_inst:
310ff103169SAhmad Fatoum 	if (retstatus == CAAM_NO_ERROR) {
3112d7a8964SCedric Neveux 		rng_privdata->instantiated = true;
312ff103169SAhmad Fatoum 		rng_privdata->pr_enabled =
313*ba7db6e0SSahil Malhotra 			caam_hal_rng_pr_enabled(rng_privdata->baseaddr) &
314*ba7db6e0SSahil Malhotra 			IS_ENABLED(CFG_CAAM_RNG_RUNTIME_PR);
315ff103169SAhmad Fatoum 
316ff103169SAhmad Fatoum 		RNG_TRACE("RNG prediction resistance is %sabled",
317ff103169SAhmad Fatoum 			  rng_privdata->pr_enabled ? "en" : "dis");
318ff103169SAhmad Fatoum 	}
3192d7a8964SCedric Neveux 
3202d7a8964SCedric Neveux 	caam_free_desc(&desc);
3212d7a8964SCedric Neveux 
3222d7a8964SCedric Neveux 	RNG_TRACE("RNG Instantiation return 0x%08x", retstatus);
3232d7a8964SCedric Neveux 
3242d7a8964SCedric Neveux 	return retstatus;
3252d7a8964SCedric Neveux }
3262d7a8964SCedric Neveux 
caam_rng_init(vaddr_t ctrl_addr)3272d7a8964SCedric Neveux enum caam_status caam_rng_init(vaddr_t ctrl_addr)
3282d7a8964SCedric Neveux {
3292d7a8964SCedric Neveux 	enum caam_status retstatus = CAAM_FAILURE;
3302d7a8964SCedric Neveux 
3312d7a8964SCedric Neveux 	RNG_TRACE("Initialization");
3322d7a8964SCedric Neveux 	retstatus = do_allocate();
3332d7a8964SCedric Neveux 	if (retstatus == CAAM_NO_ERROR) {
3342d7a8964SCedric Neveux 		rng_privdata->baseaddr = ctrl_addr;
3352d7a8964SCedric Neveux 		retstatus = caam_rng_instantiation();
3362d7a8964SCedric Neveux 	}
3372d7a8964SCedric Neveux 
3382d7a8964SCedric Neveux 	if (retstatus != CAAM_NO_ERROR)
3392d7a8964SCedric Neveux 		do_free();
3402d7a8964SCedric Neveux 
3412d7a8964SCedric Neveux 	return retstatus;
3422d7a8964SCedric Neveux }
3432d7a8964SCedric Neveux 
3442d7a8964SCedric Neveux #ifdef CFG_NXP_CAAM_RNG_DRV
3457a5015ddSRouven Czerwinski #ifdef CFG_WITH_SOFTWARE_PRNG
plat_rng_init(void)3467a5015ddSRouven Czerwinski void plat_rng_init(void)
3477a5015ddSRouven Czerwinski {
3487a5015ddSRouven Czerwinski 	TEE_Result res = TEE_SUCCESS;
3497a5015ddSRouven Czerwinski 	uint8_t buf[64] = { };
3507a5015ddSRouven Czerwinski 
3517a5015ddSRouven Czerwinski 	res = do_rng_read(buf, sizeof(buf));
3527a5015ddSRouven Czerwinski 	if (res) {
3537a5015ddSRouven Czerwinski 		EMSG("Failed to read RNG: %#" PRIx32, res);
3547a5015ddSRouven Czerwinski 		panic();
3557a5015ddSRouven Czerwinski 	}
3567a5015ddSRouven Czerwinski 
3577a5015ddSRouven Czerwinski 	res = crypto_rng_init(buf, sizeof(buf));
3587a5015ddSRouven Czerwinski 	if (res) {
3597a5015ddSRouven Czerwinski 		EMSG("Failed to initialize RNG: %#" PRIx32, res);
3607a5015ddSRouven Czerwinski 		panic();
3617a5015ddSRouven Czerwinski 	}
3627a5015ddSRouven Czerwinski 
3637a5015ddSRouven Czerwinski 	RNG_TRACE("PRNG seeded from CAAM");
3647a5015ddSRouven Czerwinski }
3657a5015ddSRouven Czerwinski #else /* !CFG_WITH_SOFTWARE_PRNG */
hw_get_random_bytes(void * buf,size_t blen)366e7d4dea3SAndrew Davis TEE_Result hw_get_random_bytes(void *buf, size_t blen)
3672d7a8964SCedric Neveux {
3682d7a8964SCedric Neveux 	if (!buf)
3692d7a8964SCedric Neveux 		return TEE_ERROR_BAD_PARAMETERS;
3702d7a8964SCedric Neveux 
3712d7a8964SCedric Neveux 	return do_rng_read(buf, blen);
3722d7a8964SCedric Neveux }
3732d7a8964SCedric Neveux 
plat_rng_init(void)374b4814b22SJorge Ramirez-Ortiz void plat_rng_init(void)
375b4814b22SJorge Ramirez-Ortiz {
376b4814b22SJorge Ramirez-Ortiz }
3777a5015ddSRouven Czerwinski #endif /* CFG_WITH_SOFTWARE_PRNG */
3787a5015ddSRouven Czerwinski #endif /* CFG_NXP_CAAM_RNG_DRV */
379