1 /*
2  * Copyright (c) 2024 - 2025, Nordic Semiconductor ASA
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright notice, this
11  *    list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * 3. Neither the name of the copyright holder nor the names of its
18  *    contributors may be used to endorse or promote products derived from this
19  *    software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #ifndef NRF_CRACEN_RNG_H__
35 #define NRF_CRACEN_RNG_H__
36 
37 #include <nrfx.h>
38 
39 #ifdef __cplusplus
40 extern "C" {
41 #endif
42 
43 /**
44  * @defgroup nrf_cracen_rng_hal CRACEN RNG HAL
45  * @{
46  * @ingroup nrf_cracen
47  * @brief   Hardware access layer for managing the Crypto Accelerator Engine (CRACEN)
48  *          Random Generator (RNG) peripheral.
49  */
50 
51 /** @brief CRACEN random generator configuration */
52 typedef struct
53 {
54     bool    enable;            /**< Enable the RNG peripheral */
55     bool    fifo_full_int_en;  /**< Enable FIFO full interrupt */
56     bool    soft_reset;        /**< Soft reset the RNG peripheral */
57     uint8_t number_128_blocks; /**< Number of 128bit blocks used for AES conditioning. Must be at least 1 */
58 } nrf_cracen_rng_control_t;
59 
60 /** @brief CRACEN random generator FSM state */
61 typedef enum
62 {
63     NRF_CRACEN_RNG_FSM_STATE_RESET        = CRACENCORE_RNGCONTROL_STATUS_STATE_RESET,    /**< RNG is not started */
64     NRF_CRACEN_RNG_FSM_STATE_STARTUP      = CRACENCORE_RNGCONTROL_STATUS_STATE_STARTUP,  /**< RNG is starting */
65     NRF_CRACEN_RNG_FSM_STATE_IDLE_READY   = CRACENCORE_RNGCONTROL_STATUS_STATE_IDLERON,  /**< RNG is idle, and ready to produce more data */
66     NRF_CRACEN_RNG_FSM_STATE_IDLE_STANDBY = CRACENCORE_RNGCONTROL_STATUS_STATE_IDLEROFF, /**< RNG is idle, with the ring oscillators off */
67     NRF_CRACEN_RNG_FSM_STATE_FILL_FIFO    = CRACENCORE_RNGCONTROL_STATUS_STATE_FILLFIFO, /**< RNG is filling the FIFO with entropy */
68     NRF_CRACEN_RNG_FSM_STATE_ERROR        = CRACENCORE_RNGCONTROL_STATUS_STATE_ERROR,    /**< RNG has halted on an error. Reset is needed */
69 } nrf_cracen_rng_fsm_state_t;
70 
71 /** Size of the RNG FIFO in bytes */
72 #define NRF_CRACEN_RNG_FIFO_SIZE ((CRACENCORE_RNGCONTROL_FIFOTHRESHOLD_ResetValue + 1) * 16)
73 
74 /**
75  * @brief Function for setting the control register
76  *
77  * @param[in] p_reg Pointer to the structure of registers of the RNG peripheral.
78  * @param[in] p_config Configuration to be written in the register.
79  */
80 NRF_STATIC_INLINE void nrf_cracen_rng_control_set(NRF_CRACENCORE_Type *            p_reg,
81                                                   nrf_cracen_rng_control_t const * p_config);
82 
83 /**
84  * @brief Function for getting the FIFO level
85  *
86  * @param[in] p_reg Pointer to the structure of registers of the RNG peripheral.
87  *
88  * @return Number of random data words ready in the FIFO
89  */
90 NRF_STATIC_INLINE uint32_t nrf_cracen_rng_fifo_level_get(NRF_CRACENCORE_Type const * p_reg);
91 
92 /**
93  * @brief Function for setting the AES conditioning KEY registers
94  *
95  * @param[in] p_reg Pointer to the structure of registers of the RNG peripheral.
96  * @param[in] index Index of the key register to be written (0..3)
97  * @param[in] value Value to be written in the register.
98  */
99 NRF_STATIC_INLINE void nrf_cracen_rng_key_set(NRF_CRACENCORE_Type * p_reg,
100                                               uint8_t               index,
101                                               uint32_t              value);
102 
103 /**
104  * @brief Function for getting the RNG FSM state
105  *
106  * @param[in] p_reg Pointer to the structure of registers of the RNG peripheral.
107  *
108  * @return State of the FSM, one of @ref nrf_cracen_rng_fsm_state_t values.
109  */
110 NRF_STATIC_INLINE
111 nrf_cracen_rng_fsm_state_t nrf_cracen_rng_fsm_state_get(NRF_CRACENCORE_Type const * p_reg);
112 
113 /**
114  * @brief Function for setting the initialization wait counter value
115  *
116  * @param[in] p_reg Pointer to the structure of registers of the RNG peripheral.
117  * @param[in] value Value to be written in the register.
118  */
119 NRF_STATIC_INLINE void nrf_cracen_rng_init_wait_val_set(NRF_CRACENCORE_Type * p_reg,
120                                                         uint16_t              value);
121 
122 /**
123  * @brief Function for setting the switch off timer value
124  *
125  * @param[in] p_reg Pointer to the structure of registers of the RNG peripheral.
126  * @param[in] value Value to be written in the register.
127  */
128 NRF_STATIC_INLINE void nrf_cracen_rng_off_timer_set(NRF_CRACENCORE_Type * p_reg,
129                                                     uint16_t              value);
130 
131 /**
132  * @brief Function for setting the entropy subsampling rate register
133  *
134  * @note The ring oscillators output is sampled at Fs=Fpclk/(ClkDiv+1)
135  *
136  * @param[in] p_reg Pointer to the structure of registers of the RNG peripheral.
137  * @param[in] value Value to be written in the register.
138  */
139 NRF_STATIC_INLINE void nrf_cracen_rng_clk_div_set(NRF_CRACENCORE_Type * p_reg,
140                                                   uint8_t               value);
141 
142 /**
143  * @brief Function for getting a word from the entropy FIFO
144  *
145  * @note The caller must ensure there is enough data by calling
146  *       @ref nrf_cracen_rng_fifo_level_get
147  *
148  * @param[in] p_reg Pointer to the structure of registers of the RNG peripheral
149  *
150  * @return Entropy word read from the FIFO
151  */
152 NRF_STATIC_INLINE uint32_t nrf_cracen_rng_fifo_get(NRF_CRACENCORE_Type const * p_reg);
153 
154 #ifndef NRF_DECLARE_ONLY
155 
nrf_cracen_rng_control_set(NRF_CRACENCORE_Type * p_reg,nrf_cracen_rng_control_t const * p_config)156 NRF_STATIC_INLINE void nrf_cracen_rng_control_set(NRF_CRACENCORE_Type *            p_reg,
157                                                   nrf_cracen_rng_control_t const * p_config)
158 {
159     p_reg->RNGCONTROL.CONTROL =
160           ((p_config->enable << CRACENCORE_RNGCONTROL_CONTROL_ENABLE_Pos)
161            & CRACENCORE_RNGCONTROL_CONTROL_ENABLE_Msk)
162         | ((p_config->fifo_full_int_en << CRACENCORE_RNGCONTROL_CONTROL_INTENFULL_Pos)
163             & CRACENCORE_RNGCONTROL_CONTROL_INTENFULL_Msk)
164         | ((p_config->soft_reset << CRACENCORE_RNGCONTROL_CONTROL_SOFTRST_Pos)
165             & CRACENCORE_RNGCONTROL_CONTROL_SOFTRST_Msk)
166         | ((p_config->number_128_blocks << CRACENCORE_RNGCONTROL_CONTROL_NB128BITBLOCKS_Pos)
167             & CRACENCORE_RNGCONTROL_CONTROL_NB128BITBLOCKS_Msk);
168 }
169 
nrf_cracen_rng_fifo_level_get(NRF_CRACENCORE_Type const * p_reg)170 NRF_STATIC_INLINE uint32_t nrf_cracen_rng_fifo_level_get(NRF_CRACENCORE_Type const * p_reg)
171 {
172     return p_reg->RNGCONTROL.FIFOLEVEL;
173 }
174 
nrf_cracen_rng_key_set(NRF_CRACENCORE_Type * p_reg,uint8_t index,uint32_t value)175 NRF_STATIC_INLINE void nrf_cracen_rng_key_set(NRF_CRACENCORE_Type * p_reg,
176                                               uint8_t index, uint32_t value)
177 {
178     p_reg->RNGCONTROL.KEY[index] = value;
179 }
180 
181 NRF_STATIC_INLINE
nrf_cracen_rng_fsm_state_get(NRF_CRACENCORE_Type const * p_reg)182 nrf_cracen_rng_fsm_state_t nrf_cracen_rng_fsm_state_get(NRF_CRACENCORE_Type const * p_reg)
183 {
184     return (nrf_cracen_rng_fsm_state_t)
185            ((p_reg->RNGCONTROL.STATUS & CRACENCORE_RNGCONTROL_STATUS_STATE_Msk)
186             >> CRACENCORE_RNGCONTROL_STATUS_STATE_Pos);
187 }
188 
nrf_cracen_rng_init_wait_val_set(NRF_CRACENCORE_Type * p_reg,uint16_t value)189 NRF_STATIC_INLINE void nrf_cracen_rng_init_wait_val_set(NRF_CRACENCORE_Type * p_reg,
190                                                         uint16_t              value)
191 {
192     p_reg->RNGCONTROL.INITWAITVAL = value;
193 }
194 
nrf_cracen_rng_off_timer_set(NRF_CRACENCORE_Type * p_reg,uint16_t value)195 NRF_STATIC_INLINE void nrf_cracen_rng_off_timer_set(NRF_CRACENCORE_Type * p_reg,
196                                                     uint16_t value)
197 {
198     p_reg->RNGCONTROL.SWOFFTMRVAL = value;
199 }
200 
nrf_cracen_rng_clk_div_set(NRF_CRACENCORE_Type * p_reg,uint8_t value)201 NRF_STATIC_INLINE void nrf_cracen_rng_clk_div_set(NRF_CRACENCORE_Type * p_reg,
202                                                   uint8_t value)
203 {
204     p_reg->RNGCONTROL.CLKDIV = value;
205 }
206 
nrf_cracen_rng_fifo_get(NRF_CRACENCORE_Type const * p_reg)207 NRF_STATIC_INLINE uint32_t nrf_cracen_rng_fifo_get(NRF_CRACENCORE_Type const * p_reg)
208 {
209     return p_reg->RNGCONTROL.FIFO[0];
210 }
211 
212 #endif // NRF_DECLARE_ONLY
213 
214 /** @} */
215 
216 #ifdef __cplusplus
217 }
218 #endif
219 
220 #endif // NRF_CRACEN_RNG_H__
221