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