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