1 /******************************************************************************
2 * @file rsi_rng.c
3 *******************************************************************************
4 * # License
5 * <b>Copyright 2024 Silicon Laboratories Inc. www.silabs.com</b>
6 *******************************************************************************
7 *
8 * SPDX-License-Identifier: Zlib
9 *
10 * The licensor of this software is Silicon Laboratories Inc.
11 *
12 * This software is provided 'as-is', without any express or implied
13 * warranty. In no event will the authors be held liable for any damages
14 * arising from the use of this software.
15 *
16 * Permission is granted to anyone to use this software for any purpose,
17 * including commercial applications, and to alter it and redistribute it
18 * freely, subject to the following restrictions:
19 *
20 * 1. The origin of this software must not be misrepresented; you must not
21 * claim that you wrote the original software. If you use this software
22 * in a product, an acknowledgment in the product documentation would be
23 * appreciated but is not required.
24 * 2. Altered source versions must be plainly marked as such, and must not be
25 * misrepresented as being the original software.
26 * 3. This notice may not be removed or altered from any source distribution.
27 *
28 ******************************************************************************/
29
30 // Include Files
31
32 #include "rsi_rom_rng.h"
33
34 /*==============================================*/
35 /**
36 * @fn uint32_t rng_start(HWRNG_Type *pRNG, uint8_t rngMode)
37 * @brief This API is used to start the Random Number Generation
38 * @param[in] pRNG : pointer to the control register
39 * @param[in] rngMode : mode of random number generation
40 * @return return RSI_OK if successful execution
41 */
rng_start(HWRNG_Type * pRNG,uint8_t rngMode)42 uint32_t rng_start(HWRNG_Type *pRNG, uint8_t rngMode)
43 {
44 if (rngMode == 0 || rngMode == 1) {
45 if (rngMode == RSI_RNG_TRUE_RANDOM) {
46 pRNG->HWRNG_CTRL_REG_b.HWRNG_RNG_ST = 1;
47 pRNG->HWRNG_CTRL_REG_b.HWRNG_PRBS_ST = 0;
48 } else {
49 pRNG->HWRNG_CTRL_REG_b.HWRNG_PRBS_ST = 1;
50 pRNG->HWRNG_CTRL_REG_b.HWRNG_RNG_ST = 0;
51 }
52 } else {
53 return ERROR_RNG_INVALID_ARG;
54 }
55 return RSI_OK;
56 }
57
rng_config_lfsr(HWRNG_Type * pRNG,rng_lfsr_config_t lfsr_config_param)58 void rng_config_lfsr(HWRNG_Type *pRNG, rng_lfsr_config_t lfsr_config_param)
59 {
60 pRNG->HWRNG_CTRL_REG_b.TAP_LFSR_INPUT = lfsr_config_param;
61 }
62
63 /*==============================================*/
64 /**
65 * @fn void rng_stop(HWRNG_Type *pRNG)
66 * @brief This API is used to stop the Random Number Generation
67 * @param[in] pRNG : pointer to the control register
68 * @return none
69 */
rng_stop(HWRNG_Type * pRNG)70 void rng_stop(HWRNG_Type *pRNG)
71 {
72 //Disabling pseudo random number and true number generation bit.
73 pRNG->HWRNG_CTRL_REG_b.HWRNG_PRBS_ST = 0;
74 pRNG->HWRNG_CTRL_REG_b.HWRNG_RNG_ST = 0;
75 }
76
77 /***************************************************************************/
78 /**
79 * @brief
80 * Read random data from the HRNG using the LFSR input latch.
81 *
82 * @details
83 * This function reads random data from the HRNG using the LFSR input latch register.
84 * The data is valid only when the LFSR_32_BIT_INPUT_VALID bit is set. After reading
85 * the data from the LFSR_INPUT_LATCH_REG, the LFSR_32_BIT_INPUT_VALID bit will be
86 * cleared by hardware.
87 *
88 * @param[in] pRNG : Pointer to the control register of the hardware random number generator.
89 * @param[out] randomBytes : Pointer to an array where the random data will be stored.
90 * @param[in] numberOfBytes : Number of bytes of random data to read.
91 *
92 * @return
93 * - RSI_OK on success.
94 * - RSI_FAIL if the LFSR_32_BIT_INPUT_VALID bit is not set or if the TAP_LFSR_INPUT bit is not set.
95 ******************************************************************************/
rng_read_lfsr_input(HWRNG_Type * pRNG,uint32_t * randomBytes,uint32_t numberOfBytes)96 uint32_t rng_read_lfsr_input(HWRNG_Type *pRNG, uint32_t *randomBytes, uint32_t numberOfBytes)
97 {
98 uint32_t status = RSI_FAIL, i;
99 if (pRNG->HWRNG_CTRL_REG_b.TAP_LFSR_INPUT == 1) {
100 for (i = 0; i < numberOfBytes; i++) {
101 // Check if LFSR input data is valid
102 if (pRNG->HWRNG_CTRL_REG_b.LFSR_32_BIT_INPUT_VALID != 0) {
103 // Read from HWRNG_LFSR_INPUT_LATCH_REG
104 randomBytes[i] = pRNG->HWRNG_LFSR_INPUT_LATCH_REG_REG_b.HWRNG_LFSR_INPUT_LATCH_REG;
105 status = RSI_OK;
106 } else {
107 status = RSI_FAIL;
108 return status;
109 }
110 }
111 } else {
112 status = RSI_FAIL;
113 }
114 return status;
115 }
116 /*==============================================*/
117 /**
118 * @fn void rng_get_bytes(HWRNG_Type *pRNG, uint32_t *randomBytes, uint32_t numberOfBytes)
119 * @brief This API is used to get the random number bytes
120 * @param[in] pRNG : pointer to the control register
121 * @param[in] randomBytes : random number register
122 * @param[in] numberOfBytes : number of bytes
123 * @return none
124 */
rng_get_bytes(HWRNG_Type * pRNG,uint32_t * randomBytes,uint32_t numberOfBytes)125 void rng_get_bytes(HWRNG_Type *pRNG, uint32_t *randomBytes, uint32_t numberOfBytes)
126 {
127 uint32_t i;
128
129 for (i = 0; i < numberOfBytes; i++) {
130 randomBytes[i] = pRNG->HWRNG_RAND_NUM_REG;
131 }
132 }
133 const ROM_RNG_API_T rng_api = { &rng_start, &rng_stop, &rng_get_bytes };
134